引言:「你的 Logo 不工作,数据库在哭泣」
\n\n如果你曾经用 PHP 编写过操作 MySQL 的脚本,那么你很可能遇到过这句吓人的话:
\nWarning: mysql_fetch_array() expects parameter 1 to be resource, boolean given。
让我们先说清楚:这不是世界末日。这仅仅是 PHP 发出的信号:「嘿,我无法从你塞给我的东西里获取数据!」。
\n\n在本教程中,我们将分析为什么会出现 mysql_fetch_array() expects parameter 1 to be resource 错误,如何修复它,最重要的是——如何一劳永逸地不再看到它(剧透:迁移到 PDO 或 MySQLi)。
本文专为 pythonlib.ru 编写——这是一个教育门户网站,我们在这里教你无痛编写代码。开始吧!
\n\n为什么 PHP 对参数报错?(原因)
\n\n要理解问题的根源,让我们回顾一下旧的 mysql_* 函数是如何工作的(是的,那些在 PHP 5.5 中就已弃用的函数)。
新手典型的代码如下所示:
\n// 连接\n$link = mysql_connect('localhost', 'user', 'password');\nmysql_select_db('test');\n\n// 查询(有错误)\n$result = mysql_query("SELECT * FROM users WHERE id = '1");\n\n// 尝试读取\nwhile($row = mysql_fetch_array($result)) { // 错误!\n echo $row['name'];\n}\n\n这里有什么问题?全是问题!但主要问题是:mysql_query() 返回了 false,而不是 resource。为什么?
- \n
- SQL 语法错误——引号未闭合。 \n
- 未连接到数据库——
mysql_connect()返回了 false。 \n - 未选择数据库——
mysql_select_db()未生效。 \n - 表不存在。 \n
当 mysql_query() 失败时,它会返回 false(布尔类型),而不是 resource。而你却试图将 false 传递给期望 resource 的 mysql_fetch_array()。冲突!错误由此产生。
哪些函数会受影响?
\n- \n
mysql_fetch_array()\n mysql_fetch_assoc()\n mysql_fetch_row()\n mysql_num_rows()\n mysql_data_seek()\n
它们都会报出同样的错误:「expects parameter 1 to be resource」。
\n\n逐步修复(针对旧代码)
\n\n如果你有遗留项目,并且暂时无法升级 PHP(虽然我非常建议升级),以下是捕获并修复错误的方法。
\n\n步骤 1. 检查连接
\n$link = mysql_connect('localhost', 'user', 'password');\nif (!$link) {\n die('连接错误:' . mysql_error());\n}\n\n步骤 2. 检查数据库选择
\nif (!mysql_select_db('my_database')) {\n die('无法选择数据库:' . mysql_error());\n}\n\n步骤 3. 执行带检查的查询
\n$sql = "SELECT * FROM users WHERE id = 1";\n$result = mysql_query($sql);\n\nif (!$result) {\n die('查询错误:' . mysql_error());\n}\n\n// 现在可以安全地使用\nwhile($row = mysql_fetch_assoc($result)) {\n echo $row['name'];\n}\n\n看到区别了吗?我们检查了每一步。如果 mysql_query() 返回了 false——我们就带着错误信息终止,而不是将 false 继续传递下去。
为什么这仍然有效?(历史背景)
\n\n在 Stack Overflow 上,这个问题已经积累了数千次浏览。这并不奇怪:许多主机上仍然运行着 PHP 5.x,而且大量教程(甚至包括 YouTube 上的)仍然在使用 mysql_* 进行教学。
但请永远记住:mysql 扩展已弃用,并从 PHP 7.0 中移除。如果你在编写新代码——请使用 mysqli 或 PDO。