当前位置: 首页 > 未分类>阅读正文

pdo 获取上次预编译执行的原生sql

2022.7.28 朱丰华 306 次 留下评论 1361字

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

本篇完,还有疑问?留下评论吧

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注