我对MySQLi非常熟悉,正在尝试PDO,我听说它更好。我正在阅读目前的教程here。他们说当PDO :: ERRMODE_EXCEPTION设置时PDO抛出异常并且我们不小心对查询做了错误(例如,输入错误,DELECT而不是SELECT)。我键入了相同的错误查询,以查看本地环境中的错误和异常消息。我在我的32位Windows 7 PC中安装了PHP 5.5,MySQL 5.6和Apache 2.4.9的最新WAMP,但没有得到我所期望的,没有异常被抛出。我尝试了教程中发布的相同代码:
try {
$DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
# UH-OH! Typed DELECT instead of SELECT!
$DBH->prepare('DELECT name FROM people');
}
catch(PDOException $e) {
echo "I'm sorry, Dave. I'm afraid I can't do that.";
file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
}
没有PDOError.txt,没有错误消息。教程或我的环境有问题吗?或者有些情况下PDO无法抛出异常?我为MySQL安装了PDO驱动程序。
答案 0 :(得分:6)
它可能会失败,因为查询永远不会被执行并且正在等待进一步的指示。
由于它认为没有触发,所以它在PDO的眼中都是有效的;这是我的比喻。
执行它,你会发现它会抛出异常。
在准备之后执行,或者是简单->query()
而不是->prepare()
。
答案 1 :(得分:6)
这实际上与您可能尚未考虑的PDO连接的另一个属性有关。这是PDO::ATTR_EMULATE_PREPARES
如果添加此属性并将其设置为false
,它将告知PDO扩展程序在发出{prepare
时向数据库发出编译,优化和执行计划的->prepare()
。 {1}}。如果不设置它,则默认值为true
,它告诉扩展名EMULATE编译。换句话说,它会等到你在编译语句之前发出->execute()
并报告错误。
PDO :: ATTR_EMULATE_PREPARES启用或禁用预准备语句的模拟。某些驱动程序不支持本机预处理语句或对它们的支持有限。使用此设置可强制PDO始终模拟预准备语句(如果为TRUE),或尝试使用本机预准备语句(如果为FALSE)。如果驱动程序无法成功准备当前查询,它将始终回退到模拟预准备语句。
因此,使用此额外的属性设置运行代码,并查看差异。
try {
$DBH = new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);
$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$DBH->setAttribute( PDO::ATTR_EMULATE_PREPARES, FALSE );
# UH-OH! Typed DELECT instead of SELECT!
$DBH->prepare('DELECT name FROM people');
}
catch(PDOException $e) {
echo "I'm sorry, Dave. I'm afraid I can't do that.";
file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
}
现在您将收到消息,并且将创建包含错误消息的文件