在迁移到PDO之前,我通过连接字符串在PHP中创建了SQL查询.如果我得到数据库语法错误,我可以回显最终的SQL查询字符串,在数据库上自己尝试,并调整它直到我修复错误,然后将其放回代码中.
准备好的PDO语句更快,更好,更安全,但有一件事困扰我:我从未看到最终查询,因为它被发送到数据库.当我在Apache日志或我的自定义日志文件中出现语法错误时(我在catch
块中记录错误),我看不到导致它们的查询.
有没有办法捕获PDO发送到数据库的完整SQL查询并将其记录到文件中?
Pas*_*TIN 97
你这样说:
我从未看到最终查询,因为它被发送到数据库
嗯,实际上,在使用预准备语句时,没有" 最终查询 " 这样的东西:
那么,回答你的问题:
有没有办法捕获PDO发送到数据库的完整SQL查询并将其记录到文件中?
否:由于任何地方都没有" 完整的SQL查询 ",因此无法捕获它.
出于调试目的,您可以做的最好的事情是通过将值注入语句的SQL字符串来"重构""真正的"SQL查询.
在这种情况下,我通常做的是:
var_dump
(或等效)来显示参数的值在调试方面,这并不是很好 - 但这是准备好的报表的价格及其带来的好处.
Nat*_*ong 84
虽然Pascal MARTIN是正确的,PDO不会立即将完整的查询发送到数据库,但是ryeguy建议使用DB的日志记录功能实际上允许我查看由数据库组装和执行的完整查询.
方法如下:(这些说明适用于Windows机器上的MySQL - 您的里程可能会有所不同)
my.ini
该[mysqld]
部分下,添加一个log
命令,如log="C:\Program Files\MySQL\MySQL Server 5.1\data\mysql.log"
该文件将快速增长,因此请确保在完成测试后将其删除并关闭日志记录.
小智 16
当然,您可以使用此模式进行调试{{ PDO::ATTR_ERRMODE }}
只需在查询之前添加新行,然后您将显示调试行.
$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
$db->query('SELECT *******');
Run Code Online (Sandbox Code Playgroud)
fij*_*ron 14
您可能想要做的是使用debugDumParams() 它不会为您构建准备好的语句,但它会显示您的参数.
don*_*ain 12
一个旧帖子,但也许有人会觉得这很有用;
function pdo_sql_debug($sql,$placeholders){
foreach($placeholders as $k => $v){
$sql = preg_replace('/:'.$k.'/',"'".$v."'",$sql);
}
return $sql;
}
Run Code Online (Sandbox Code Playgroud)
这是一个函数,可以看到有效的SQL将来自php.net上的 "Mark"评论:
function sql_debug($sql_string, array $params = null) {
if (!empty($params)) {
$indexed = $params == array_values($params);
foreach($params as $k=>$v) {
if (is_object($v)) {
if ($v instanceof \DateTime) $v = $v->format('Y-m-d H:i:s');
else continue;
}
elseif (is_string($v)) $v="'$v'";
elseif ($v === null) $v='NULL';
elseif (is_array($v)) $v = implode(',', $v);
if ($indexed) {
$sql_string = preg_replace('/\?/', $v, $sql_string, 1);
}
else {
if ($k[0] != ':') $k = ':'.$k; //add leading colon if it was left out
$sql_string = str_replace($k,$v,$sql_string);
}
}
}
return $sql_string;
}
Run Code Online (Sandbox Code Playgroud)
没有.PDO查询不是在客户端准备的.PDO只是将SQL查询和参数发送到数据库服务器.该数据库是什么呢取代(的?
"S).您有两种选择:
例如你有这个 pdo 语句:
$query="insert into tblTest (field1, field2, field3)
values (:val1, :val2, :val3)";
$res=$db->prepare($query);
$res->execute(array(
':val1'=>$val1,
':val2'=>$val2,
':val3'=>$val3,
));
Run Code Online (Sandbox Code Playgroud)
现在您可以通过定义这样的数组来获取执行的查询:
$assoc=array(
':val1'=>$val1,
':val2'=>$val2,
':val3'=>$val3,
);
$exQuery=str_replace(array_keys($assoc), array_values($assoc), $query);
echo $exQuery;
Run Code Online (Sandbox Code Playgroud)
除了检查错误日志之外,几乎没有关于错误显示的内容,但有一个相当有用的功能:
<?php
/* Provoke an error -- bogus SQL syntax */
$stmt = $dbh->prepare('bogus sql');
if (!$stmt) {
echo "\PDO::errorInfo():\n";
print_r($dbh->errorInfo());
}
?>
Run Code Online (Sandbox Code Playgroud)
(来源链接)
很明显,可以修改此代码以用作异常消息或任何其他类型的错误处理
归档时间: |
|
查看次数: |
131750 次 |
最近记录: |