我正在尝试向用户返回尽可能多的信息,并且我希望能够告诉他们他们刚刚执行的某个操作是否有警告,例如,如果数据由于被塞进太短的字段而被截断,或者他们试图将字母或小数放入整数字段中。
为了测试的目的,我在一个单独的页面上减少了我的代码:
<?php
error_reporting(E_ALL);
ini_set('display_errors', True);
session_start();
include '../php/security.php';
sec::dieifnotvalid();
include '../php/db_connection_params.php';
$pdo_conn = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
$qry_string = "insert into tbl_engine (capacity) values (?)";
$var_array = array('gfd');
$q = $pdo_conn->prepare($qry_string);
$q->execute($var_array);
$return_arr = $q->fetchAll();
var_dump($q->errorInfo());
?>
如果我尝试执行这样的操作,
$qry_string = "insert into tbl_manufacturer_lookup (manufacturer_name) values (?)";
$var_array = array('Audi');
将一个重复条目插入到唯一列中,我得到
array(3) { [0]=> string(5) "00000" [1]=> int(1062) [2]=> string(57) "Duplicate entry 'Audi' for key 'manufacturer_name_UNIQUE'" }
打印在页面上。这很好。
但是如果我这样做,
$qry_string = "insert into tbl_engine (capacity) values (?)";
$var_array = array('hjgt');
向整数字段插入字符串时,errorinfo为
array(3) { [0]=> string(5) "HY000" [1]=> NULL [2]=> NULL }
,这与插入整数值完全相同。
通过比较,MySQL工作台将返回如下内容:1 row(s) affected, 1 warning(s): 1366 Incorrect integer value: 'fdd' for column 'capacity' at row 1
我真的想让我的web应用程序返回一些有用的东西像这样
执行SHOW WARNINGS
查询。
对于那些正在寻找的人来说,一个快速而简单的方法是使用查询SHOW WARNINGS
。这是一个可以根据需要重用的简单函数。
function lastWarning($pdo)
{
var_dump($pdo->query("SHOW WARNINGS")->fetch());
}
你可以把它做得尽可能漂亮。例如,在PDO子类中:
namespace Foo;
class PDO extends 'PDO
{
public function getWarning()
{
$warnings = $this->query('SHOW WARNINGS')->fetch();
if ($warning['Level'] == 'Error') {
return "Warning: {$warning['Message']} [#{$warning['Code']}]'n";
}
}
}
如果我是你,我就不会依赖这样的警告。在PHP中,您应该简单地执行额外的查询和验证数据,并显示一些警告(例如,对于重复的唯一键)或应该是整数的字段(但它们不是)。
否则,你可能会在数据库中插入一些不应该放在那里的数据(例如,5,52作为小数会有问题,也许你应该在PHP中纠正它,或者让用户输入正确的值)
要提取PDO警告,请像这样初始化PDO对象:
$pdo_conn = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass, array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING
));
注意,这只能用于调试目的,因为消息通常包含敏感信息。