PHP 的 mysql_query() 返回值探究
一、前言
前段时间学校 PHP 结课的时候做了一个课程设计,一个在线留言板,今天在把该程序部署到服务器上的时候遇到了一些问题,解决之后也算是对 mysql_query()
这个函数有了更深的认识,写个博文记录一下。
在写这个留言板的时候尝试了用面向对象的思想来写,自然的,数据库的操作也封装成了类的一个个方法,关于 Query 的方法我是这么写的:
1 | /** |
由于自己电脑上的开发环境用的是 PHP7,而学校机房用的是旧的 PHP5,而在 PHP7 中,mysql 系列的函数都被废弃了,取而代之的是 mysqli 系列函数,因此在这个方法上我也加了关于 PHP 版本的判断,根据版本来使用不同的请求函数。
二、问题出现
整个程序在本地跑起来是没有任何的问题的,增删查改都运行正常,而今天部署到服务器上 (环境是PHP5) 后,数据库的 Query 操作都出现了异常,无法正常取得数据。
以用户登录为例:
1 | $db = Database::getInstance(); |
这段代码在我本地(PHP7)运行起来没有任何的问题,而在服务器(PHP5)上,不管用户是否输入了正确的密码,结果都会跳转到主页 index.php 去。很显然,问题出现在返回的值 $Result
上。
三、解决问题
回过头来看看我是怎么处理 mysql_query()
的返回值的:
1 | if ($PHP < 7){ |
在此以前,我对于 mysql_query()
的理解是,有结果返回,他就是个 mysql_result
类型,否则,他就是个 bool
类型,代表执行的成功与失败,所以我用 instanceof mysql_result
判断它是否是资源类型,如果不是,则直接返回;如果是,则继续下一步的遍历获取结果。
于是,我在 login 的代码打了个断点,输出 $Result
的值然后 die()
掉:
1 | $db = Database::getInstance(); |
结果让我意外,尽管我用户名和密码乱打一通,但是返回的 $Result
居然是个资源类型(输出值大概是 Resource #XXXXXX)。于是我赶紧上 php 官网查文档,得知
mysql_query() 仅对 SELECT,SHOW,DESCRIBE, EXPLAIN 和其他语句 语句返回一个 resource,如果查询出现错误则返回 FALSE。
对于其它类型的 SQL 语句,比如INSERT, UPDATE, DELETE, DROP 之类, mysql_query() 在执行成功时返回 TRUE,出错时返回 FALSE。
来源:http://php.net/manual/zh/function.mysql-query.php#refsect1-function.mysql-query-returnvalues
登录查表用的是 SELECT
语句,所以它必定返回的是个 Resource 资源类型,难怪到了 PHP5 上查询会出问题。所以,我将查询的方法做了以下修改:
1 | if ($PHP < 7){ |
使用 is_bool()
判断返回值 $result
是否是布尔值 true or false,如果不是,那它必定就是资源类型,然后进一步遍历获取查询结果。保存之,再重新尝试登录,果然问题解决了。程序其它地方的查询问题也一并解决了。
四、继续深究
既然 SELECT
查询必定返回的是一个资源值,为什么我在本地 PHP7 的环境没有遇到以上问题?我继续在 php 官网查询了 mysqli_query()
的文档:
失败时返回 FALSE,通过mysqli_query() 成功执行SELECT, SHOW, DESCRIBE或 EXPLAIN查询会返回一个mysqli_result 对象,其他查询则返回TRUE。
来源:http://php.net/manual/zh/mysqli.query.php#refsect1-mysqli.query-returnvalues
所以看出区别了,mysql_query()
返回的是一个资源类型,而 mysqli_query()
返回的是一个资源对象。
所以难怪我在 PHP7 中不会遇到这样的 BUG。因为 instanceof
主要就是用来确认一个变量是否是某个类的实例。而对于没有结果的查询,mysqli_fetch_array
则会返回一个空数组,当 if
判断一个空数组的时候,就会返回 false
。
继续查看关于 Resource 资源类型 的文档说明,得知这个 Resource 它还分为 数据库连接资源、文件资源 和 文档资源,可以用 get_resource_type() 来获取它的具体类型,又涨姿势了。
最后,我的 Query 方法改成了如下代码:(其实只改动了一处)
1 | if ($PHP < 7){ |
五、结语
自己在试一个函数的时候,千万不能根据各种情况试了它的返回值之后就以为就是那样子的,一定要以官方文档为准←_←
程序的兼容性真的很重要,只顾着测试 PHP7 是否运行正常,而没有在 PHP5 上进行测试。假如老师的电脑上用的是 PHP 5… emmmmmm…. 不知道会不会影响我的期末分数((((
遇到问题的时候,查 Google,查文档!!
后话:
这个留言板已经成功部署到服务器上啦,地址在此:https://project.crazykid.moe/php-guestbook/
同时也将源码挂到 Github 上了,repo地址:https://github.com/CrazyKidCN/PHP-GuestBook
初学者,请各位大佬多多指教> <