引言:那个让你想关掉浏览器的错误
如果你曾经用 PHP 向 MySQL 发送查询,然后在浏览器中突然看到类似这样的信息:
Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /var/www/site/index.php on line 15...那么你懂那种感觉。似乎一切正确:连接了,写了查询,但 PHP 却对你报红。尤其当代码在本地服务器上能运行,但在主机上却不行时,更让人沮丧。或者反过来。
这个错误是 Stack Overflow 上最常见的问题之一。成千上万的开发者(包括我们)都曾为此抓耳挠腮,试图理解:“为什么参数 1 期望是 resource,却得到了 boolean?”
在本文中,我们不仅会分析原因,还会走完完整的流程:从复现错误到修复它。同时,我们也会看看为什么旧的 mysql_* 函数早就该被现代的 PDO 或 MySQLi 所取代。开始吧!
问题在实际中如何表现
让我们模拟一个场景。你有一个 users 表,想要列出所有用户。代码是用老式方法写的:
$link = mysql_connect('localhost', 'user', 'password');mysql_select_db('test');
$result = mysql_query("SELECT * FROM users");
while ($row = mysql_fetch_array($result)) { echo $row['name'] . '<br>';}看起来是经典写法。但如果 users 表不存在,或者 SQL 有语法错误,那么 mysql_query() 返回的就不是 resource,而是 false。于是 mysql_fetch_array() 接收到了 boolean 而不是 resource —— 错误由此产生。
大多数情况下,问题就出在查询执行失败上。但让我们按顺序分析所有可能的原因。
原因 #1:SQL 查询返回了 false
这是最常见的情况。如果查询失败,mysql_query() 会返回 false。例如:
- 表不存在
- 字段名错误
- SQL 语法错误
- 访问权限问题
如何检查? 只需在查询后添加检查:
$result = mysql_query("SELECT * FROM non_existent_table");
if (!$result) { die('查询错误:' . mysql_error());}
while ($row = mysql_fetch_array($result)) { // ...}这会立即显示问题所在。mysql_error() 会输出错误文本,例如:"Table 'test.non_existent_table' doesn't exist"。
原因 #2:数据库连接丢失
有时连接会中断(例如,由于超时或 MySQL 重启)。此时 mysql_query() 也会返回 false。解决方案是始终检查连接:
$link = mysql_connect('localhost', 'user', 'password');if (!$link) { die('无法连接:' . mysql_error());}但即使这样也不是万能的。最好使用能够自动重新连接的函数——例如 MySQLi。
原因 #3:混淆了 mysql_* 和 mysqli_* 函数
另一个常见情况。你可能会不小心混用两个不同的库。例如,通过 mysqli_connect() 连接,但通过 mysql_query() 执行查询。这行不通:mysql_query() 期望的是来自 mysql_connect() 的 resource,而不是来自 mysqli_connect() 的。
这是一个混淆的例子:
// 通过 MySQLi 连接$link = mysqli_connect('localhost', 'user', 'password', 'test');
// 但通过旧的 mysql_* 查询$result = mysql_query("SELECT * FROM users"); // 错误!
while ($row = mysql_fetch_array($result)) { echo $row['name'];}解决方案是坚持使用同一个库。要