Getting raw SQL query string from PDO prepared statements

前端 未结 16 865
心在旅途
心在旅途 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:03

    Mike's answer is working good until you are using the "re-use" bind value.
    For example:

    SELECT * FROM `an_modules` AS `m` LEFT JOIN `an_module_sites` AS `ms` ON m.module_id = ms.module_id WHERE 1 AND `module_enable` = :module_enable AND `site_id` = :site_id AND (`module_system_name` LIKE :search OR `module_version` LIKE :search)
    

    The Mike's answer can only replace first :search but not the second.
    So, I rewrite his answer to work with multiple parameters that can re-used properly.

    public function interpolateQuery($query, $params) {
        $keys = array();
        $values = $params;
        $values_limit = [];
    
        $words_repeated = array_count_values(str_word_count($query, 1, ':_'));
    
        # build a regular expression for each parameter
        foreach ($params as $key => $value) {
            if (is_string($key)) {
                $keys[] = '/:'.$key.'/';
                $values_limit[$key] = (isset($words_repeated[':'.$key]) ? intval($words_repeated[':'.$key]) : 1);
            } else {
                $keys[] = '/[?]/';
                $values_limit = [];
            }
    
            if (is_string($value))
                $values[$key] = "'" . $value . "'";
    
            if (is_array($value))
                $values[$key] = "'" . implode("','", $value) . "'";
    
            if (is_null($value))
                $values[$key] = 'NULL';
        }
    
        if (is_array($values)) {
            foreach ($values as $key => $val) {
                if (isset($values_limit[$key])) {
                    $query = preg_replace(['/:'.$key.'/'], [$val], $query, $values_limit[$key], $count);
                } else {
                    $query = preg_replace(['/:'.$key.'/'], [$val], $query, 1, $count);
                }
            }
            unset($key, $val);
        } else {
            $query = preg_replace($keys, $values, $query, 1, $count);
        }
        unset($keys, $values, $values_limit, $words_repeated);
    
        return $query;
    }
    

提交回复
热议问题