为啥这个 PDO 语句会默默地失败?
Posted
技术标签:
【中文标题】为啥这个 PDO 语句会默默地失败?【英文标题】:Why does this PDO statement silently fail?为什么这个 PDO 语句会默默地失败? 【发布时间】:2015-09-18 09:20:28 【问题描述】:这是我的 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));
【问题讨论】:
请不要自己滚动密码散列。 PHP 提供password_hash()
和password_verify()
请使用它们。这里有一些good ideas about passwords如果你使用的是5.5之前的PHP版本there is a compatibility pack available here
【参考方案1】:
有时您的 PDO 代码会产生类似 Call to a member function execute()
或类似的错误。或者甚至没有任何错误,但查询并不完全一样。这意味着您的查询未能执行。
每次查询失败时,mysql 都会有一条错误消息解释原因。不幸的是,默认情况下,此类错误不会传输到 PHP,您所拥有的只是上面提到的沉默或神秘的错误消息。因此,配置 PHP 和 PDO 以报告 MySQL 错误非常重要。一旦您收到错误消息,解决问题将不费吹灰之力。
为了获得有关问题的详细信息,请在连接后立即将以下行放入代码中
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
(其中$dbh
是您的 PDO 实例变量的名称)或者 - 更好地 - 将此参数添加为 connection option。之后,所有数据库错误都将被转换为 PDO 异常,如果不理会这些异常,它将像常规 PHP 错误一样。
收到错误信息后,您必须阅读并理解它。这听起来太明显了,但学习者经常忽略错误消息的含义。然而,大多数时候它非常简单地解释了这个问题:
比如说,如果它说某个特定的表不存在,您必须检查拼写、错别字、字母大小写。您还必须确保您的 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_reporting
应始终设置为 E_ALL
。
另请注意,尽管存在常见的错觉,不必使用 try-catch 来报告错误。 PHP 会以更好的方式报告 PDO 错误。未捕获的异常非常适合开发,但是如果您想显示自定义的错误页面,仍然不要为此使用 try catch,而只需设置一个custom error handler。简而言之,您不必将 PDO 错误视为特殊的东西,而是将它们视为代码中的任何其他错误。
附言 有时没有错误但也没有结果。那么这意味着,没有符合您的条件的数据。所以你必须承认这个事实,即使你可以发誓数据和标准都是对的。他们不是。您必须再次检查它们。我有一个简短的答案,可以帮助您查明匹配问题,Having issue with matching rows in the database using PDO。只需按照此说明和链接教程一步一步地解决您的问题或对 Stack Overflow 有一个可回答的问题。
【讨论】:
这如何回答 OP 的问题? @NaijaProgrammer id 没有,但它可以引导他/她根据“你的常识”建议的错误报告找到答案.. @Your Common Sense:我的一个新问题,同样的问题。根本原因是在创建 PDO 对象时在选项中设置了ATTR_EMULATE_PREPARES
选项。生产中断(php 7.2.8),在开发中工作(php 7.2.34)!!!在某些情况下,导致随机失败的是选项的设置(而不是正在设置的选项的值)。以上是关于为啥这个 PDO 语句会默默地失败?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 MediaElement 有时会默默地失败,我该如何纠正它?