mysql_fetch_array()/mysql_fetch_assoc()/mysql_fetch_row()/mysql_num_rows等...期望参数 1 为 Resource

mysql_fetch_array()/mysql_fetch_assoc()/mysql_fetch_row()/mysql_num_rows etc... expects parameter 1 to be resource

提问人:iamjonesy 提问时间:6/4/2010 最后编辑:Dharmaniamjonesy 更新时间:8/3/2022 访问量:775872

问:

我正在尝试从MySQL表中选择数据,但收到以下错误消息之一:

mysql_fetch_array() 期望参数 1 是资源,给定布尔值

这是我的代码:

$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'];
}
PHP 的MySQL

评论

15赞 nik 6/4/2010
你可以使用以下命令获得更有用的 eroor msg:: QUERY or die(mysql_error());
124赞 Felix Kling 6/4/2010
另外必须注意的是:您的代码容易发生 SQL 注入您应该验证和/或转义用户输入。看一看mysql_real_escape_string永远不要相信用户数据。
7赞 szgal 7/4/2014
实际上,OP的代码会在MySQL服务器上引起语法错误,但至少它容易受到SQL注入的影响,因为单引号没有变量插值。
4赞 3/13/2017
@FelixKling我意识到这很古老,而且可能是当时最准确的,但您的评论现在在某种程度上是错误的:不是 SQL 注入保护的全部和最终目的;它仍然容易受到许多攻击。(不,你从来没有说过它是完美的,但你暗示这是唯一需要的解决方案)据我所知,现在最好的解决方案是 PDO。mysql_real_escape_string
2赞 Mark Amery 11/16/2018
嘎。将这个问题扩展到包括 MySQLi 和 PDO 是一个坏主意。他们每个人都有自己略有不同的语法和错误消息,他们很可能有自己的问题。将所有内容组合成一个巨大的三部分问题只会使它更难被谷歌搜索,并迫使到达这里的人们涉足不相关的内容来获得他们想要的东西。它也使下面的许多答案无效,并且按照我们通常采用的标准,这个问题“过于宽泛”。在我看来,这是一团糟,但现在修复为时已晚。

答:

680赞 Edward Dale 6/4/2010 #1

查询可能由于各种原因而失败,在这种情况下,mysql_* 和 mysqli 扩展都将从各自的查询函数/方法返回。您需要测试该错误条件并相应地处理它。false

mysql_扩展

注意mysql_函数已弃用,并在 php 版本 7 中删除。

在将其传递给 之前进行检查。你会发现这是因为查询失败。请参阅 [][1] 文档,了解可能的返回值以及如何处理它们的建议。$resultmysql_fetch_arrayfalsemysql_query

$username = mysql_real_escape_string($_POST['username']);
$password = $_POST['password'];
$result = mysql_query("SELECT * FROM Users WHERE UserName LIKE '$username'");

if($result === FALSE) { 
    trigger_error(mysql_error(), E_USER_ERROR);
}

while($row = mysql_fetch_array($result))
{
    echo $row['FirstName'];
}

评论

9赞 2ndkauboy 6/4/2010
没错,但是如果查询失败,使用 die() 有点多。
30赞 Edward Dale 6/4/2010
我打算为 OP 设计一个完整的错误处理机制,但认为这可能超出了我的回答范围。
0赞 Sepster 4/24/2013
@scompt.com 是的,其他几个答案也涵盖了它。我想我只是想说,由于这是一个高可见度问题的公认答案,除了关于将来如何正确捕获错误的(优秀)建议外,它应该(恕我直言)实际上回答了特定问题(即解释为什么在这种情况下会出现错误)。
2赞 anestv 6/17/2014
而不是你可以使用 .如果我错了,请纠正我if($result === FALSE)if(! $result)
1赞 Greg 12/26/2014
mysql_query():mysql 扩展已弃用,将来将被删除:使用 mysqli
51赞 Matteo Riva 6/4/2010 #2

用引号括起来。字符串值(与数值相反)必须用引号括起来。$username

$result = mysql_query("SELECT * FROM Users WHERE UserName LIKE '$username'");

此外,如果您不使用通配符,则使用条件是没有意义的:如果您需要完全匹配,请使用 .LIKE=LIKE

评论

2赞 HoldOffHunger 3/20/2016
如果$username是:“ ';删除表;“ ?这就是使用准备好的语句和绑定值的优势,我认为提问者希望保留这些优势。
113赞 nik 6/4/2010 #3

此处发生的错误是由于使用了单引号 ()。你可以像这样提出你的查询:'

mysql_query("
SELECT * FROM Users 
WHERE UserName 
LIKE '".mysql_real_escape_string ($username)."'
");

它用于防止 SQL 注入。 虽然我们应该使用 MySQLi 或 PDO_MYSQL 扩展来升级 PHP 版本(PHP 5.5.0 及更高版本),但对于旧版本就可以了。mysql_real_escape_stringmysql_real_escape_string

评论

5赞 Matteo Riva 6/5/2010
为什么要使用字符串连接来添加噪声,而不仅仅是将变量放在查询字符串中?
1赞 nik 8/7/2012
@Matteo Riva 是的,但我认为这是将变量与字符串分开的更简洁的方法。:)
58赞 2ndkauboy 6/4/2010 #4

scompt.com 所述,查询可能会失败。使用此代码获取查询的错误或正确的结果:

$username = $_POST['username'];
$password = $_POST['password'];

$result = mysql_query("
SELECT * FROM Users 
WHERE UserName LIKE '".mysql_real_escape_string($username)."'
");

if($result)
{
    while($row = mysql_fetch_array($result))
    {
        echo $row['FirstName'];
    }
} else {
    echo 'Invalid query: ' . mysql_error() . "\n";
    echo 'Whole query: ' . $query; 
}

有关详细信息,请参阅 mysql_query() 的文档

实际错误是单引号,因此变量未被解析。但你真的应该用它来避免SQL注入。$usernamemysql_real_escape_string($username)

40赞 Chaitannya 6/4/2010 #5

你的代码应该是这样的

$username = $_POST['username'];
$password = $_POST['password'];
$query = "SELECT * FROM Users WHERE UserName LIKE '$username'";
echo $query;
$result = mysql_query($query);

if($result === FALSE) {
    die(mysql_error("error message for the user")); 
}

while($row = mysql_fetch_array($result))
{
    echo $row['FirstName'];
}

完成此操作后,您将在屏幕上打印查询。在您的服务器上尝试此查询,看看它是否产生所需的结果。大多数情况下,错误出在查询中。其余代码是正确的。

评论

3赞 Brad 12/8/2014
请勿使用此代码。它很容易受到 SQL 注入攻击。
33赞 derokorian 1/8/2012 #6
$result = mysql_query('SELECT * FROM Users WHERE UserName LIKE $username');

您可以使用单引号定义字符串,并且 PHP 不会解析单引号分隔的字符串。为了获得变量插值,您需要使用双引号或字符串连接(或它们的组合)。有关详细信息,请参阅 http://php.net/manual/en/language.types.string.php

此外,您应该检查mysql_query返回了有效的结果资源,否则 fetch_*、num_rows 等将无法处理结果,因为这不是结果!IE浏览器:

$username = $_POST['username'];
$password = $_POST['password'];
$result = mysql_query('SELECT * FROM Users WHERE UserName LIKE $username');

if( $result === FALSE ) {
   trigger_error('Query failed returning error: '. mysql_error(),E_USER_ERROR);
} else {
   while( $row = mysql_fetch_array($result) ) {
      echo $row['username'];
   }
}

http://us.php.net/manual/en/function.mysql-query.php 了解更多信息。

评论

2赞 Brad 12/8/2014
即使添加引号,也不要使用此代码。它很容易受到 SQL 注入攻击。
41赞 yasin 4/25/2012 #7

请检查一旦选择的数据库没有选择,因为有时没有选择数据库

检查

mysql_select_db('database name ')or DIE('Database name is not available!');

在MySQL查询之前 ,然后转到下一步

$result = mysql_query('SELECT * FROM Users WHERE UserName LIKE $username');

f($result === FALSE) {
    die(mysql_error());
164赞 John Conde 7/27/2012 #8

当您的查询中出现导致其失败的错误时,将显示此错误消息。当使用时,它会表现出来:

  • mysql_fetch_array/mysqli_fetch_array()
  • mysql_fetch_assoc()/mysqli_fetch_assoc()
  • mysql_num_rows()/mysqli_num_rows()

注意:如果查询没有影响任何行,则不会显示此错误。只有语法无效的查询才会生成此错误。

疑难解答步骤

  • 确保已将开发服务器配置为显示所有错误。您可以通过将其放在文件顶部或配置文件中来执行此操作:error_reporting(-1);。如果您有任何语法错误,这将向您指出它们。

  • 使用 mysql_error()。 将报告MySQL在执行查询时遇到的任何错误。mysql_error()

用法示例:

    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_*函数不应用于新代码。它们不再维护,社区已开始弃用过程。相反,您应该了解准备好的语句并使用 PDOMySQLi。如果您无法决定,本文将为您提供选择帮助。如果你想学习,这里有一个很好的PDO教程

评论

1赞 Funk Forty Niner 5/5/2017
鉴于今天 stackoverflow.com/q/43804651/1415724 和最近其他类似问题的问题;我认为更新您的答案以包含类似“该错误也可能是由于未使用 mysql_query() / mysqli_query($connection) 等执行查询而引起的”;思潮?由于此问答中没有其他答案提及这一点。
27赞 kolexinfos 9/6/2012 #9

如果您尝试了此处的所有方法,但不起作用,则可能需要检查MySQL数据库排序规则。我的设置为瑞典语排序规则。然后我把它改成了,一切都进入了齿轮。utf8_general_ci

24赞 Amjad Omari 2/25/2013 #10

试试这个,它一定是有效的,否则你需要打印错误来指定你的问题

$username = $_POST['username'];
$password = $_POST['password'];

$sql = "SELECT * from Users WHERE UserName LIKE '$username'";
$result = mysql_query($sql,$con);

while($row = mysql_fetch_array($result))
{
    echo $row['FirstName'];
}

评论

8赞 deceze 2/25/2013
1) 对 SQL 注入完全开放,2) 不包括导致 OP 案例中的错误的错误处理。
0赞 Sepster 4/23/2013
+1.@deceze 是的,它是敞开的。但不再如此,OP 或接受的应答者的代码 ;-)并不是 OP 代码中缺乏错误处理导致了错误......这是错误,这个答案至少试图解决这个问题(通过在表达式中将单引号括在字符串文字上)。LIKE
1赞 asim-ishaq 5/5/2013
+1 请在 LIKE 和“$username”之间添加一个空格,除了 SQL 注入之外,其余似乎都很好。为什么不使用 = 而不是 LIKE 运算符用户名必须完全匹配
32赞 Enis P. Aginić 4/23/2013 #11

此查询应该有效:

$result = mysql_query("SELECT * FROM Users WHERE UserName LIKE '%$username%'");
while($row = mysql_fetch_array($result))
{
    echo $row['FirstName'];
}

问题是单引号,因此您的查询失败并返回 FALSE,并且您的 WHILE 循环无法执行。使用 % 可以匹配包含字符串的任何结果(例如 SomeText-$username-SomeText)。

这只是对你问题的回答,你应该实现其他帖子中提到的内容:错误处理,使用转义字符串(用户可以在字段中输入任何内容,并且你必须确保它不是任意代码),使用PDO代替mysql_connect现在已经被剥夺了。

8赞 user2155518 4/29/2013 #12

首先,检查与数据库的连接。连接成功与否?

如果完成了,那么在那之后,我编写了这段代码,并且运行良好:

if (isset($_GET['q1mrks']) && isset($_GET['marks']) && isset($_GET['qt1'])) {
    $Q1mrks = $_GET['q1mrks'];
    $marks = $_GET['marks'];
    $qt1 = $_GET['qt1'];

    $qtype_qry = mysql_query("
        SELECT *
        FROM s_questiontypes
        WHERE quetype_id = '$qt1'
    ");
    $row = mysql_fetch_assoc($qtype_qry);
    $qcode = $row['quetype_code'];

    $sq_qry = "
        SELECT *
        FROM s_question
        WHERE quetype_code = '$qcode'
        ORDER BY RAND() LIMIT $Q1mrks
    ";
    $sq_qry = mysql_query("
        SELECT *
        FROM s_question
        WHERE quetype_code = '$qcode'
        LIMIT $Q1mrks
    ");
    while ($qrow = mysql_fetch_array($sq_qry)) {
        $qm = $qrow['marks'] . "<br />";
        $total += $qm . "<br />";
    }
    echo $total . "/" . $marks;
}

评论

2赞 Brad 12/8/2014
请勿使用此代码。它很容易受到 SQL 注入攻击。
20赞 asim-ishaq 5/5/2013 #13

可能有两个原因:

  1. 在调用函数之前是否打开了与数据库mysql_query连接?我在你的代码中没有看到这一点。在进行查询之前使用 mysql_connect。看php.net/manual/en/function.mysql-connect.php

  2. 变量 $username 在单引号字符串中使用,因此不会在查询中计算其值。查询肯定会失败。

第三,查询结构容易发生SQL注入。您可以使用准备好的语句来避免此安全威胁。

27赞 Dip Pokhrel 5/10/2013 #14
$username = $_POST['username'];
$password = $_POST['password'];
$result = mysql_query("SELECT * FROM Users WHERE UserName LIKE '%$username%'") or die(mysql_error());

while($row = mysql_fetch_array($result))
{
    echo $row['FirstName'];
}

有时将查询抑制为@mysql_query(your query);

评论

3赞 Brad 12/8/2014
请勿使用此代码。它很容易受到 SQL 注入攻击。
19赞 ravi 5/30/2013 #15

请尝试以下代码。它可能工作正常。

$username = $_POST['username'];
$password = $_POST['password'];
$result = mysql_query("SELECT * FROM Users WHERE UserName ='$username'");

while($row = mysql_fetch_array($result))
{
    echo $row['FirstName'];
}

评论

4赞 Brad 12/8/2014
此代码受 SQL 注入的影响,不应使用。
5赞 Omdev 7/6/2013 #16

首先检查您的连接。

然后,如果你想从数据库中获取确切的值,那么你应该写:

$username = $_POST['username'];
$password = $_POST['password'];
$result = mysql_query("SELECT * FROM Users WHERE UserName =`$usernam`");

或者你想获取值的类型,那么你应该写:LIKE

$result = mysql_query("SELECT * FROM Users WHERE UserName LIKE '%$username%'");

评论

3赞 Brad 12/8/2014
此代码对 SQL 注入完全开放,不应使用。
24赞 Gears.of.Codes 7/22/2013 #17
$query = "SELECT Name,Mobile,Website,Rating FROM grand_table order by 4";

while( $data = mysql_fetch_array($query))
{
    echo("<tr><td>$data[0]</td><td>$data[1]</td><td>$data[2]</td><td>$data[3]</td></tr>");      
}

您可以使用此 ORDER BY 查询,而不是使用 WHERE 查询。对于使用查询来说,这比这要好得多。

我已经完成了这个查询,没有收到参数或布尔值等错误。

评论

0赞 Brad 12/8/2014
请记住在 HTML 上下文中使用任意数据时使用。否则,当数据中使用保留字符时,可能会创建有效的 HTML。htmlspecialchars()
13赞 Janak Prajapati 9/19/2013 #18
<?php
    $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'];
    }
?>

如果有一个用户具有唯一的用户名,则可以为此使用“=”。没有必要喜欢。

您的查询将是:

mysql_query("SELECT * FROM Users WHERE UserName ='".$username."'");

评论

3赞 Brad 12/8/2014
此代码对 SQL 注入完全开放,不应使用。
0赞 Brad 6/29/2015
@AnujGarg 此代码采用直接输入并将其连接到查询中。有人可以在发布数据中编写自己的 SQL,然后执行。username
0赞 Anuj Garg 6/30/2015
那么用什么来防止代码注入呢?
15赞 user2835116 10/1/2013 #19

转到您的 .我有同样的问题。验证用户名和密码,并且 sql select 与配置同名。config.php

14赞 Durairaj 10/30/2013 #20

在 MySQL 查询之前包含连接字符串变量。例如,在此代码中:$connt

$results = mysql_query($connt, "SELECT * FROM users");

评论

1赞 Paul Spiegel 2/13/2020
这并不能解决问题中的问题。这也是错误的,并且会引发另一个错误。
5赞 user28864 12/16/2013 #21

您还可以在执行 fetch 数组之前检查是否像这样失败$result

$username = $_POST['username'];
$password = $_POST['password'];
$result = mysql_query('SELECT * FROM Users WHERE UserName LIKE $username');
if(!$result)
{
     echo "error executing query: "+mysql_error(); 
}else{
       while($row = mysql_fetch_array($result))
       {
         echo $row['FirstName'];
       }
}

评论

3赞 Brad 12/8/2014
请勿使用此代码。它很容易受到 SQL 注入攻击。
0赞 user28864 12/8/2014
但是,如果代码有效,我觉得您应该编辑代码并输入所需的过滤器,而不是对代码进行谴责。
0赞 Brad 12/8/2014
简单地使用过滤器并不能解决此代码的问题。最好的解决方案是将准备好的/参数化查询与 PDO 或类似查询一起使用。我认为修复它没有任何意义,因为正确答案已经发布在这里。理想情况下,此答案将被删除。但是,欢迎您修正您的答案,如果它是正确的,我很乐意投票。
0赞 user28864 12/9/2014
好吧,如果你觉得答案不值得考虑,你可以继续阅读它。然而,我认为这个社区的全部意义在于分享和贡献知识。如果你有东西要分享,而不是展示和推迟人们。
2赞 Brad 12/9/2014
你是对的,这个社区的全部意义在于分享知识。这就是为什么在我的反对票中添加了解释,并进一步解释了为什么您的过滤器建议不够。我更愿意提醒你,以及其他任何找到你答案的人,上面的代码是不安全的。每个人都最好学习正确的方法,而不是让糟糕的代码永久化。而且,我不能删除你的答案,我也不会。如果您选择这样做,这取决于您。
3赞 Engr Saddam Zardari 1/21/2014 #22

通常,当数据库连接失败时会发生错误,因此请确保连接数据库或包含数据库文件。

include_once(db_connetc.php');

// Create a connection
$connection = mysql_connect("localhost", "root", "") or die(mysql_error());

//Select database
mysql_select_db("db_name", $connection) or die(mysql_error());

$employee_query = "SELECT * FROM employee WHERE `id` ='".$_POST['id']."'";

$employee_data = mysql_query($employee_query);

if (mysql_num_rows($employee_data) > 0) {

    while ($row = mysql_fetch_array($employee_data)){
        echo $row['emp_name'];
    } // end of while loop
} // end of if
  • 最佳做法是在 sqlyog 中运行查询,然后将其复制到页面代码中。
  • 始终将查询存储在变量中,然后回显该变量。然后传递给 .mysql_query($query_variable);

评论

2赞 Phil 1/21/2014
1)你不知道我是否在这里对任何答案投了赞成票或反对票。2)正如我在第一条评论中解释的那样;您的答案没有引用问题(布尔值传递给mysql_fetch_array),并且您有语法错误
2赞 Phil 1/21/2014
两个代码示例中的引号不正确。应用于第二个代码块的语法突出显示是一个死的赠品,表明有问题
4赞 Brad 12/8/2014
此代码受 SQL 注入的影响,不应使用。@EngrZardari,如果您在生产系统上使用此代码,您无疑已被黑客入侵,并且应该使用带有 PDO 或类似功能的准备好/参数化查询来补救这种情况。有些机器人可以自动测试此类漏洞。
1赞 Funk Forty Niner 11/21/2018
@EngrZardari关于您的“没有任何错误,我已将当前使用的代码粘贴到此处。 上面的评论。查询中缺少一个引号,我更正了该引号。这将引发 (PHP) 解析错误。
1赞 Ritesh d joshi 4/28/2014 #23

试试这段代码,它工作正常

将 POST 变量赋给变量

   $username = $_POST['uname'];

   $password = $_POST['pass'];

  $result = mysql_query('SELECT * FROM userData WHERE UserName LIKE $username');

if(!empty($result)){

    while($row = mysql_fetch_array($result)){
        echo $row['FirstName'];
     }
}

评论

3赞 Brad 12/8/2014
此代码会受到 SQL 注入攻击,不应使用。
8赞 A.Aleem11 10/13/2014 #24

确保你没有在之前使用 db_close() 关闭数据库 运行查询:

如果您在脚本中使用多个查询,即使您包含包含查询或数据库连接的其他页面,那么在任何地方使用 db_close() 可能会关闭您的数据库连接,因此请确保您没有在脚本中犯此错误。

7赞 user1012181 11/8/2014 #25

如果在检查时没有出现任何 MySQL 错误,请确保正确创建了数据库表。这发生在我身上。查找任何不需要的逗号或引号。

10赞 Dennis Kiptugen 4/7/2015 #26
<?php
      $username = $_POST['username'];
       $password = $_POST['password'];

     $result = mysql_query("SELECT * FROM Users WHERE UserName LIKE '".mysql_real_escape_string($username)."'")or die(mysql_error());
while($row=mysql_fetch_array($result))
  {
 echo $row['FirstName'];
 }
 ?>
14赞 Manoj Dhiman 4/16/2015 #27

不要使用 depricated mysql_* 函数(在 php 5.5 中 depriced 将在 php 7 中删除)。您可以使用mysqliPDO来实现这一点

下面是完整的 SELECT 查询

<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
} 

$sql = "SELECT id, firstname, lastname FROM MyGuests";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    // output data of each row
    while($row = $result->fetch_assoc()) {
        // code here 
    }
} else {
    echo "0 results";
}
$conn->close();
?>

评论

0赞 Paul Spiegel 2/13/2020
您的帖子没有处理问题解决的问题,这些问题是无效的查询和不恰当的错误报告。这篇文章跑题了。
11赞 SuReSh 4/28/2015 #28

试试这个

$username = $_POST['username'];
$password = $_POST['password'];
$result = mysqli_query('SELECT * FROM Users WHERE UserName LIKE $username');

if($result){
while($row = mysqli_fetch_array($result))
{
    echo $row['FirstName'];
}
}

评论

4赞 Manoj Dhiman 5/25/2015
@panjehra mysql_* 现在已被剥夺,并将从 PHP 7 中删除。请改用 mysqli_*
11赞 Jay Blanchard 8/6/2015 #29

任何时候你得到...

“警告:mysqli_fetch_object() 期望参数 1 mysqli_result,给定布尔值”

...这可能是因为您的查询存在问题。or 可能会返回(布尔值),但这个通用的失败消息不会给你留下太多线索。你如何发现你的查询有什么问题?你prepare()query()FALSE

首先,确保错误报告已打开且可见:在文件顶部紧跟打开标记后添加以下两行:<?php

error_reporting(E_ALL);
ini_set('display_errors', 1);

如果在 php.ini 中设置了错误报告,则不必担心这一点。只要确保你优雅地处理错误,永远不要向你的用户透露任何问题的真正原因。向公众揭示真正的原因对于那些想要损害您的网站和服务器的人来说可能是一个金色的邀请。如果您不想向浏览器发送错误,您可以随时监控 Web 服务器错误日志。日志位置因服务器而异,例如,在 Ubuntu 上,错误日志通常位于 。如果要在 Linux 环境中检查错误日志,则可以在控制台窗口中实时查看错误。或者当你制作它们时。/var/log/apache2/error.logtail -f /path/to/log

一旦你解决了标准错误报告,在数据库连接和查询上添加错误检查将为你提供有关所发生问题的更多细节。请看一下此示例,其中列名不正确。首先,返回一般致命错误消息的代码:

$sql = "SELECT `foo` FROM `weird_words` WHERE `definition` = ?";
$query = $mysqli->prepare($sql)); // assuming $mysqli is the connection
$query->bind_param('s', $definition);
$query->execute();

该错误是通用的,对您解决正在发生的事情没有多大帮助。

通过多写几行代码,你可以得到非常详细的信息,你可以用它来立即解决问题。检查声明的真实性,如果良好,您可以继续绑定和执行。prepare()

$sql = "SELECT `foo` FROM `weird_words` WHERE `definition` = ?";
if($query = $mysqli->prepare($sql)) { // assuming $mysqli is the connection
    $query->bind_param('s', $definition);
    $query->execute();
    // any additional code you need would go here.
} else {
    $error = $mysqli->errno . ' ' . $mysqli->error; // 1054 Unknown column 'foo' in 'field list'
    // handle error
}

如果出现问题,您可以吐出一条错误消息,直接将您带到问题所在。在这种情况下,表中没有列,解决问题是微不足道的。foo

如果愿意,可以将此检查包含在函数或类中,并通过如前所述优雅地处理错误来扩展它。

评论

2赞 Paul Spiegel 2/13/2020
你怎么能在一篇文章中写出“只要确保你优雅地处理错误,永远不要向你的用户透露任何问题的真正原因”?echo $error;
0赞 Jay Blanchard 2/13/2020
感谢您的提醒@PaulSpiegel。我已经有一段时间没有写或重新审视答案了,并且错过了我把回声留在那里的。
0赞 Dennis Kiptugen 10/5/2015 #30

由于 $username 是一个 PHP 变量,我们需要将其作为字符串传递给 MySQLI,因此,由于在查询中,您将使用双引号、单引号和句号进行连接(“'.$username.'”),如果您以双引号开头,您将反转引号 ('“.$username.”')。

$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'];
     }

$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'];
     }

但是使用Mysql已经贬值了很多,使用PDO instead.it 很简单,但非常安全

评论

0赞 Dennis Kiptugen 10/5/2015
但是 Mysql 的使用已经贬值了。您可以改用 PDO。让我给你一个登录示例。
2赞 SpacePhoenix 4/13/2018
密码永远不应该以纯文本形式存储,利用 PHP 的内置功能来处理密码的哈希和哈希密码的验证!
0赞 Avro_Abir 5/17/2021
请勿使用此代码。它很容易受到 SQL 注入攻击。
2赞 Paul Spiegel 4/7/2019 #31

传统上,PHP 对代码中的不良实践和失败是宽容的, 这使得调试变得非常困难。 在这种特定情况下的问题是,默认情况下,mysqliPDO 都不会告诉您,当查询失败时,只会返回 . (我不会谈论被剥夺的mysql扩展。 对预准备语句的支持是切换到 PDOmysqli 的原因。 但是,您可以更改 PHP 的默认行为,使其在查询失败时始终抛出异常FALSE

对于 PDO:使用$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

error_reporting(E_ALL);

$pdo = new PDO("mysql:host=localhost;dbname=test", "test","");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$result = $pdo->query('select emal from users');
$data = $result->fetchAll();

这将向您显示以下内容:

致命错误:未捕获的异常“PDOException”,并显示消息“SQLSTATE[42S22]:找不到列:第 8 行 E:\htdocs\test\mysql_errors\pdo.php 中的”字段列表“中的 1054 未知列”emal”

PDOException:SQLSTATE[42S22]:未找到列:第 8 行 E:\htdocs\test\mysql_errors\pdo.php 中的“字段列表”中的 1054 未知列“emal”

正如你所看到的,它准确地告诉你,查询出了什么问题,以及在代码中修复它的位置。

没有你会得到$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

致命错误:对第 9 行 E:\htdocs\test\mysql_errors\pdo 中布尔值调用成员函数 fetchAll(.php)

对于 mysqli:使用mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

error_reporting(E_ALL);

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'test', '', 'test');

$result = $mysqli->query('select emal from users');
$data = $result->fetch_all();

你会得到

致命错误:未捕获异常“mysqli_sql_exception”,消息“Unknown column 'emal' in 'field list' in E:\htdocs\test\mysql_errors\mysqli.php on line 8

mysqli_sql_exception:第 8 行 E:\htdocs\test\mysql_errors\mysqli .php 的“字段列表”中的未知列“emal”

没有你,你只会得到mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

致命错误:在第 10 行的 E:\htdocs\test\mysql_errors\mysqli.php 中的布尔值上调用成员函数 fetch_all()

当然,您可以手动检查MySQL错误。 但是,如果每次我打错字时都必须这样做,我会发疯的—— 或者更糟 - 每次我想查询数据库时。