为什么此 PDO 语句以静默方式失败?

2022-08-30 10:25:25

这是我的PHP SQL语句,它在var转储时返回false

$sql = $dbh->prepare('INSERT INTO users(full_name, e_mail, username, password) VALUES (:fullname, :email, :username, :password)');
$result = $sql->execute(array(
                    ':fullname' => $_GET['fullname'], 
                    ':email' => $_GET['email'], 
                    ':username' => $_GET['username'],
                    ':password' => $password_hash));

答案 1

TL;DR

  1. 始终在 PDO 连接代码中设置为 。它将让数据库告诉您实际问题是什么,无论是查询,服务器,数据库还是其他什么。PDO::ATTR_ERRMODEPDO::ERRMODE_EXCEPTION
  2. 始终将 SQL 查询中的每个 PHP 变量替换为问号,并使用预准备语句执行查询。这将有助于避免各种语法错误。

解释

有时,您的 PDO 代码会产生类似或类似的错误。或者即使没有任何错误,但查询的工作方式也不完全相同。这意味着您的查询无法执行。Call to a member function execute()

每次查询失败时,MySQL都会有一条错误消息来解释原因。不幸的是,默认情况下,此类错误不会转移到PHP,您所拥有的只是一个沉默或上面提到的神秘错误消息。因此,配置PHP和PDO以报告MySQL错误非常重要。一旦您收到错误消息,就可以毫不费力地解决问题。

为了获取有关问题的详细信息,请在连接后立即在代码中放置以下行

$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

(其中 是 PDO 实例变量的名称)或 - 最好 - 将此参数添加为连接选项。之后,所有数据库错误都将转换为PDO异常,如果将其单独保留,将像常规PHP错误一样起作用。$dbh

收到错误消息后,您必须阅读并理解它。这听起来太明显了,但学习者经常忽略错误消息的含义。然而,大多数时候,它解释的问题非常简单:

  • 比如说,如果它说一个特定的表不存在,你必须检查拼写,拼写错误,字母大小写。此外,您必须确保PHP脚本连接到正确的数据库
  • 或者,如果它说SQL语法中存在错误,那么您必须检查您的SQL。问题点就在错误消息中引用的查询部分之前

您还必须信任错误消息。如果它说令牌的数量与绑定变量的数量不匹配,那么它就是如此。对于缺少的表或列也是如此。如果可以选择,无论是你自己的错误还是错误消息是错误的,都要坚持前者。这听起来很居高临下,但这个网站上的数百个问题证明这个建议非常有用。


请注意,为了查看PDO错误,您必须能够看到PHP错误。为此,您必须根据站点环境配置 PHP:

  • 开发服务器上,在屏幕上显示错误非常方便,为此必须打开显示错误:

      error_reporting(E_ALL);
      ini_set('display_errors',1);
    
  • 实时站点上,必须记录所有错误,但永远不会向客户端显示。为此,请按以下方式配置 PHP:

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

请注意,应始终设置为。error_reportingE_ALL

另请注意,尽管存在常见的错觉,但错误报告不必使用 try-catch。PHP已经以更好的形式报告您的PDO错误。未捕获的异常对开发非常有利,但是如果要显示自定义的错误页面,仍然不要为此使用try catch,而只需设置自定义错误处理程序即可。简而言之,您不必将PDO错误视为特殊错误,而是将它们视为代码中的任何其他错误。

附言:
有时没有错误,但也没有结果。然后这意味着,没有数据符合您的标准。所以你必须承认这个事实,即使你可以发誓数据和标准都是正确的。事实并非如此。您必须再次检查它们。我有一个简短的答案,可以帮助您查明匹配问题,使用PDO在数据库中匹配行时遇到问题。只需按照此说明和链接的教程逐步进行操作,就可以解决您的问题或为Stack Overflow提供可回答的问题。


答案 2

推荐