pdo预编译无法直接获取原生sql
可以通过字符串替换,拼接得到真正的sql
函数代码如下:
/** 存储上次执行的sql
* @param string $sql 预编译sql语句
* @param array $args 预编译sql参数
*/
function setSql($sql="",$args=array())
{
$sql = str_replace(";","",$sql);
//判断是关联数组 OR 索引数组
$args_value = array_values($args);
$arg_is_key = array_diff_key($args,$args_value);
//判断sql是?还是:key
$sql_is_key = strpos($sql,"?")===false;
//如果是 ? ,则遍历替换即可
if(!$sql_is_key){
foreach($args as $k=>$v) {
if(is_string($v)) $v="'$v'";
$sql=preg_replace('/\?/',$v,$sql,1);
}
}
//如果是 :key ,且 args 是关联数组,则遍历替换
elseif($arg_is_key){
foreach($args as $k=>$v) {
if(is_string($v)) $v="'$v'";
$sql=str_replace(":$k",$v,$sql);
}
}
//如果是 :key ,且 args 是索引数组
else{
//提取键名(通常为 :key ,也就是 : 开头, 空格结尾,则使用 \w 单词字符开头,\s 空格结尾)
$sql .= " ";
preg_match_all('/:\w+\s/', $sql, $matches);
$keys = $matches[0];
//遍历赋值
for ($i=0; $i<count($keys); $i++){
$key = str_replace(" ",'',$keys[$i]);
if(is_string($args[$i])) $args[$i]="'$args[$i]'";
$sql=str_replace("$key",$args[$i],$sql);
}
$sql = substr($sql,0,-1);
}
//记录sql
echo $sql;
}
调用函数:
setSql("select * from user where utype=:utype and uname=:uname",['utype'=>1,'uname'=>'张伟']); // 键名统一不要加:
echo "<br>";
setSql("select * from user where utype=:utype and uname=:uname",[1,'张伟']);
echo "<br>";
setSql("select * from user where utype=? and uname=?",[1,'张伟']);
运行结果:
select * from user where utype=1 and uname='张伟'
select * from user where utype=1 and uname='张伟'
select * from user where utype=1 and uname='张伟'
提示:pdo的debugDumpParams可以获得调试sql,但并不能直接使用(包含其他参数,不能直接执行使用)。
$pdo -> debugDumpParams
本篇完,还有疑问?留下评论吧