Getting raw SQL query string from PDO prepared statements

前端 未结 16 892
心在旅途
心在旅途 2020-11-22 06:56

Is there a way to get the raw SQL string executed when calling PDOStatement::execute() on a prepared statement? For debugging purposes this would be extremely useful.

16条回答
  •  太阳男子
    2020-11-22 07:02

    I need to log full query string after bind param so this is a piece in my code. Hope, it is useful for everyone hat has the same issue.

    /**
     * 
     * @param string $str
     * @return string
     */
    public function quote($str) {
        if (!is_array($str)) {
            return $this->pdo->quote($str);
        } else {
            $str = implode(',', array_map(function($v) {
                        return $this->quote($v);
                    }, $str));
    
            if (empty($str)) {
                return 'NULL';
            }
    
            return $str;
        }
    }
    
    /**
     * 
     * @param string $query
     * @param array $params
     * @return string
     * @throws Exception
     */
    public function interpolateQuery($query, $params) {
        $ps = preg_split("/'/is", $query);
        $pieces = [];
        $prev = null;
        foreach ($ps as $p) {
            $lastChar = substr($p, strlen($p) - 1);
    
            if ($lastChar != "\\") {
                if ($prev === null) {
                    $pieces[] = $p;
                } else {
                    $pieces[] = $prev . "'" . $p;
                    $prev = null;
                }
            } else {
                $prev .= ($prev === null ? '' : "'") . $p;
            }
        }
    
        $arr = [];
        $indexQuestionMark = -1;
        $matches = [];
    
        for ($i = 0; $i < count($pieces); $i++) {
            if ($i % 2 !== 0) {
                $arr[] = "'" . $pieces[$i] . "'";
            } else {
                $st = '';
                $s = $pieces[$i];
                while (!empty($s)) {
                    if (preg_match("/(\?|:[A-Z0-9_\-]+)/is", $s, $matches, PREG_OFFSET_CAPTURE)) {
                        $index = $matches[0][1];
                        $st .= substr($s, 0, $index);
                        $key = $matches[0][0];
                        $s = substr($s, $index + strlen($key));
    
                        if ($key == '?') {
                            $indexQuestionMark++;
                            if (array_key_exists($indexQuestionMark, $params)) {
                                $st .= $this->quote($params[$indexQuestionMark]);
                            } else {
                                throw new Exception('Wrong params in query at ' . $index);
                            }
                        } else {
                            if (array_key_exists($key, $params)) {
                                $st .= $this->quote($params[$key]);
                            } else {
                                throw new Exception('Wrong params in query with key ' . $key);
                            }
                        }
                    } else {
                        $st .= $s;
                        $s = null;
                    }
                }
                $arr[] = $st;
            }
        }
    
        return implode('', $arr);
    }
    

提交回复
热议问题