我试图从 MySQL 表中选择数据,但我收到以下错误消息之一:
mysql_fetch_array()期望参数 1 是资源,给定布尔值
要么
mysqli_fetch_array()期望参数 1 为 mysqli_result,给定布尔值
要么
在布尔 / 非对象上调用成员函数 fetch_array()
这是我的代码:
$username = $_POST['username'];
$password = $_POST['password'];
$result = mysql_query('SELECT * FROM Users WHERE UserName LIKE $username');
while($row = mysql_fetch_array($result)) {
echo $row['FirstName'];
}
这同样适用于代码
$result = mysqli_query($mysqli, 'SELECT ...');
// mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given
while( $row=mysqli_fetch_array($result) ) {
...
和
$result = $mysqli->query($mysqli, 'SELECT ...');
// Call to a member function fetch_assoc() on a non-object
while( $row=$result->fetch_assoc($result) ) {
...
和
$result = $pdo->query('SELECT ...', PDO::FETCH_ASSOC);
// Invalid argument supplied for foreach()
foreach( $result as $row ) {
...
和
$stmt = $mysqli->prepare('SELECT ...');
// Call to a member function bind_param() on a non-object
$stmt->bind_param(...);
和
$stmt = $pdo->prepare('SELECT ...');
// Call to a member function bindParam() on a non-object
$stmt->bindParam(...);
查询可能由于各种原因而失败,在这种情况下,mysql_ * 和 mysqli 扩展将从它们各自的查询函数 / 方法返回false
。您需要测试该错误情况并相应地处理它。
注意 mysql_函数已弃用 ,已在 php 7 中删除。
在将$result
传递给mysql_fetch_array
之前检查$result
。您会发现它是false
因为查询失败了。有关可能的返回值以及如何处理它们的建议,请参阅mysql_query
文档。
$username = mysql_real_escape_string($_POST['username']);
$password = $_POST['password'];
$result = mysql_query("SELECT * FROM Users WHERE UserName LIKE '$username'");
if($result === FALSE) {
die(mysql_error()); // TODO: better error handling
}
while($row = mysql_fetch_array($result))
{
echo $row['FirstName'];
}
mysqli 扩展
程序风格 :
$username = mysqli_real_escape_string($mysqli, $_POST['username']);
$result = mysqli_query($mysqli, "SELECT * FROM Users WHERE UserName LIKE '$username'");
// mysqli_query returns false if something went wrong with the query
if($result === FALSE) {
yourErrorHandler(mysqli_error($mysqli));
}
else {
// as of php 5.4 mysqli_result implements Traversable, so you can use it with foreach
foreach( $result as $row ) {
...
oo 风格 :
$username = $mysqli->escape_string($_POST['username']);
$result = $mysqli->query("SELECT * FROM Users WHERE UserName LIKE '$username'");
if($result === FALSE) {
yourErrorHandler($mysqli->error); // or $mysqli->error_list
}
else {
// as of php 5.4 mysqli_result implements Traversable, so you can use it with foreach
foreach( $result as $row ) {
...
使用准备好的声明:
$stmt = $mysqli->prepare('SELECT * FROM Users WHERE UserName LIKE ?');
if ( !$stmt ) {
yourErrorHandler($mysqli->error); // or $mysqli->error_list
}
else if ( !$stmt->bind_param('s', $_POST['username']) ) {
yourErrorHandler($stmt->error); // or $stmt->error_list
}
else if ( !$stmt->execute() ) {
yourErrorHandler($stmt->error); // or $stmt->error_list
}
else {
$result = $stmt->get_result();
// as of php 5.4 mysqli_result implements Traversable, so you can use it with foreach
foreach( $result as $row ) {
...
这些例子只是说明了应该做什么 (错误处理),而不是如何去做。生产代码在输出 HTML 时不应使用or die
,否则它将(至少)生成无效的 HTML。此外,不应向非管理员用户显示数据库错误消息,因为它公开了太多信息 。
当您的查询中出现导致其失败的错误时,将显示此错误消息。使用时它会表现出来:
mysql_fetch_array
/ mysqli_fetch_array()
mysql_fetch_assoc()
/ mysqli_fetch_assoc()
mysql_num_rows()
/ mysqli_num_rows()
注意 :如果查询不影响任何行,则不会出现此错误。只有语法无效的查询才会生成此错误。
故障排除步骤
确保将开发服务器配置为显示所有错误。您可以将它放在文件的顶部或配置文件中: error_reporting(-1);
。如果您有任何语法错误,这将指出它们。
使用mysql_error()
。 mysql_error()
将报告 MySQL 在执行查询时遇到的任何错误。
样品用法:
mysql_connect($host, $username, $password) or die("cannot connect");
mysql_select_db($db_name) or die("cannot select DB");
$sql = "SELECT * FROM table_name";
$result = mysql_query($sql);
if (false === $result) {
echo mysql_error();
}
从 MySQL 命令行或phpMyAdmin 等工具运行查询。如果您的查询中有语法错误,这将告诉您它是什么。
确保你的报价是正确的。查询或值周围缺少引号可能导致查询失败。
确保你逃避你的价值观。查询中的引号可能导致查询失败(并且还允许您对 SQL 注入开放)。使用mysql_real_escape_string()
来转义输入。
确保你没有混合mysqli_*
和mysql_*
函数。它们不是同一个东西,不能一起使用。 (如果你要选择一个或另一个使用mysqli_*
。请参阅下面的原因。)
其他提示
mysql_*
函数不应该用于新代码。它们不再维护,社区已开始弃用过程 。相反,您应该了解准备好的语句并使用PDO或MySQLi 。如果你无法决定, 这篇文章将有助于选择。如果你想学习,这是一个很好的 PDO 教程 。
这里发生的错误是由于使用单引号( '
)。您可以像这样输入查询:
mysql_query("
SELECT * FROM Users
WHERE UserName
LIKE '".mysql_real_escape_string ($username)."'
");
它使用mysql_real_escape_string
来防止 SQL 注入。虽然我们应该使用 MySQLi 或 PDO_MYSQL 扩展来升级 PHP 版本(PHP 5.5.0 及更高版本),但是对于旧版本, mysql_real_escape_string
可以解决问题。