mysql_fetch_array() 错误:参数 1 必须是 resource — 如何修复

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:「你的 Logo 不工作,数据库在哭泣」

\n\n

如果你曾经用 PHP 编写过操作 MySQL 的脚本,那么你很可能遇到过这句吓人的话:
\nWarning: mysql_fetch_array() expects parameter 1 to be resource, boolean given。

\n\n

让我们先说清楚:这不是世界末日。这仅仅是 PHP 发出的信号:「嘿,我无法从你塞给我的东西里获取数据!」。

\n\n

在本教程中,我们将分析为什么会出现 mysql_fetch_array() expects parameter 1 to be resource 错误,如何修复它,最重要的是——如何一劳永逸地不再看到它(剧透:迁移到 PDO 或 MySQLi)。

\n\n

本文专为 pythonlib.ru 编写——这是一个教育门户网站,我们在这里教你无痛编写代码。开始吧!

\n\n

为什么 PHP 对参数报错?(原因)

\n\n

要理解问题的根源,让我们回顾一下旧的 mysql_* 函数是如何工作的(是的,那些在 PHP 5.5 中就已弃用的函数)。

\n\n

新手典型的代码如下所示:

\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\n
    \n
  • SQL 语法错误——引号未闭合。
  • \n
  • 未连接到数据库——mysql_connect() 返回了 false。
  • \n
  • 未选择数据库——mysql_select_db() 未生效。
  • \n
  • 表不存在。
  • \n
\n\n

当 mysql_query() 失败时,它会返回 false(布尔类型),而不是 resource。而你却试图将 false 传递给期望 resource 的 mysql_fetch_array()。冲突!错误由此产生。

\n\n

哪些函数会受影响?

\n
    \n
  • mysql_fetch_array()
  • \n
  • mysql_fetch_assoc()
  • \n
  • mysql_fetch_row()
  • \n
  • mysql_num_rows()
  • \n
  • mysql_data_seek()
  • \n
\n\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. 检查数据库选择

\n
if (!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

为什么这仍然有效?(历史背景)

\n\n

在 Stack Overflow 上,这个问题已经积累了数千次浏览。这并不奇怪:许多主机上仍然运行着 PHP 5.x,而且大量教程(甚至包括 YouTube 上的)仍然在使用 mysql_* 进行教学。

\n\n

但请永远记住:mysql 扩展已弃用,并从 PHP 7.0 中移除。如果你在编写新代码——请使用 mysqli 或 PDO。

博客

书籍推荐