PDO 데이터베이스 쿼리를 디버깅하는 방법?


140

PDO로 이동하기 전에 문자열을 연결하여 PHP에서 SQL 쿼리를 작성했습니다. 데이터베이스 구문 오류가 발생하면 최종 SQL 쿼리 문자열을 에코하고 데이터베이스에서 직접 시도하여 오류를 수정할 때까지 조정 한 다음 코드에 다시 넣을 수 있습니다.

준비된 PDO 문은 더 빠르고 안전하며 안전하지만 한 가지가 나를 귀찮게합니다. 최종 쿼리가 데이터베이스로 전송되는 것을 보지 못했습니다. Apache 로그 또는 사용자 정의 로그 파일의 구문에 대한 오류가 발생하면 ( catch블록 내에 오류를 기록함 ) 오류 를 일으킨 쿼리를 볼 수 없습니다.

PDO가 데이터베이스로 보낸 전체 SQL 쿼리를 캡처하여 파일에 기록하는 방법이 있습니까?


4
그것은 되는 파일에 기록 : /var/log/mysql/*. PDO 바운드 매개 변수는 구문 오류를 유발할 수 없으므로 준비된 SQL 쿼리 만 있으면됩니다.
Xeoncross

1
stackoverflow.com/questions/210564/… (허용되지 않은 답변) 의 코드를 참조하십시오 . 몇 가지 업데이트가 게시 된 것은 아닙니다.
Mawg는 모니카

1
Composer를 통한 간단한 한 줄 : github.com/panique/pdo-debug
Sliq

2
Xeoncross의 답변이 도움이되었습니다. 이 기능을 켜는 방법을 설명하는 기사입니다. 많은 서버 설치에서 기본적으로 해제되어 있습니다. pontikis.net/blog/how-and-when-to-enable-mysql-logs
mrbinky3000

2
함께 시도var_dump($pdo_instance->debugDumpParams())
Daniel Petrovaliev

답변:


99

당신은 이것을 말합니다 :

데이터베이스로 전송되는 최종 쿼리를 보지 못했습니다.

실제로, 준비된 명령문을 사용할 때 " final query " 와 같은 것은 없습니다 .

  • 먼저, 성명서를 DB로 보내어 준비한다
    • 데이터베이스는 쿼리를 구문 분석하고 쿼리의 내부 표현을 작성합니다.
  • 그리고 변수를 바인드하고 명령문을 실행할 때 변수 만 데이터베이스로 전송됩니다.
    • 데이터베이스는 값을 명령문의 내부 표현에 "주입"합니다.


따라서 귀하의 질문에 대답하려면 :

PDO가 데이터베이스로 보낸 전체 SQL 쿼리를 캡처하여 파일에 기록하는 방법이 있습니까?

아니요 : " 전체 SQL 쿼리 "가 어디에도 없으므로이를 캡처 할 방법이 없습니다.


디버깅 목적으로 수행 할 수있는 최선의 방법은 값을 명령문의 SQL 문자열에 삽입하여 "실제"SQL 쿼리를 "재구성"하는 것입니다.

이런 종류의 상황에서 내가 보통하는 일은 다음과 같습니다.

  • 자리 표시 자와 함께 명령문에 해당하는 SQL 코드를 에코합니다.
  • 매개 변수의 값을 표시하기 위해 직후에 var_dump (또는 이에 상응하는) 사용
  • 실행할 수있는 "실제"쿼리가없는 경우에도 일반적으로 가능한 오류를 볼 수 있습니다.

이것은 디버깅과 관련하여 훌륭하지는 않지만 준비된 명령문의 가격과 장점입니다.


1
좋은 설명-감사합니다. 분명히 나는 ​​이것이 어떻게 작동하는지에 대한 퍼지 아이디어 만 가지고있었습니다. 명령문이 준비되면 결과 오브젝트에 플러그인 할 매개 변수를 사용하여 데이터베이스로 다시 보낼 수있는 해시 또는 숫자 ID가 포함되어 있다고 가정합니다.
Nathan Long

천만에요 :-) ;;; 나는 이것이 어떻게 세부적으로 구현되는지는 모르지만, 그것이 그런식이라고 생각합니다. 결과는 정확히 그렇습니다. ;;; 그것은 준비된 문장으로 좋은 것 중 하나입니다. 동일한 쿼리를 여러 번 실행 해야하는 경우 DB로 전송되고 한 번만 준비됩니다. 각 실행마다 데이터 만 전송됩니다.
Pascal MARTIN

1
업데이트 : Aaron Patterson은 Railsconf 2011에서 Rails에 준비된 문장을 더 추가했지만 그 이점은 MySQL보다 PostgreSQL에서 훨씬 더 크다고 언급했습니다. 그는 MySQL이 준비된 쿼리를 실행할 때까지 쿼리 계획을 실제로 만들지 않기 때문이라고 말했다.
Nathan Long

85

데이터베이스 로그를 보면

하지만 파스칼 마틴은 PDO 번에 모든 데이터베이스의 전체 쿼리를 전송하지 않습니다 정확한지, ryeguy DB를의 로깅 기능을 사용하기의 제안은 실제로 조립 및 데이터베이스에 의해 실행 나를는 전체 쿼리를 볼 수있었습니다.

방법은 다음과 같습니다 (이 지침은 Windows 컴퓨터의 MySQL에 대한 것입니다-마일리지는 다를 수 있음)

  • 에서는 my.ini의 아래 [mysqld]절의 경우, 추가 log등의 명령을log="C:\Program Files\MySQL\MySQL Server 5.1\data\mysql.log"
  • MySQL을 다시 시작하십시오.
  • 해당 파일의 모든 쿼리를 기록하기 시작합니다.

해당 파일은 빠르게 커지므로 테스트가 끝나면 파일을 삭제하고 로깅을 해제하십시오.


1
참고로-. ini에서 슬래시를 피해야했습니다. 그래서 내 항목은 log = "C : \\ temp \\ MySQL \\ mysql.log"와 비슷했습니다.
Jim

4
의 설정에 따라 작동합니다 PDO::ATTR_EMULATE_PREPARES. 자세한 내용은이 답변을 참조하십시오. stackoverflow.com/questions/10658865/#answer-10658929
webbiedave

23
이 때문에 PDO가 싫어.
Salman

1
@webbiedave-오,와! 귀하의 링크 된 답변은 PDO가 최적으로 작동하지 않고 이전 버전의 MySQL 또는 이전 드라이버와의 하위 호환성을 위해 전체 쿼리를 보내는 경우에만 작동합니다. 흥미 롭군
Nathan Long

13
MySQL 5.5 이상에서는 general_log대신에 필요 합니다 log. 참조 dev.mysql.com/doc/refman/5.5/en/query-log.html
아드리안 맥닐에게

18

물론이 모드를 사용하여 디버깅 할 수 {{ PDO::ATTR_ERRMODE }} 있습니다. 쿼리 앞에 새 줄을 추가하면 디버그 줄이 표시됩니다.

$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
$db->query('SELECT *******');  

->query준비된 문장을 사용할 때 전화하지 않습니까?
EoghanM

고마워요, 저에게 많은 도움이되었습니다! :)
휴식

17

아마도 원하는 것은 명령문 핸들에서 debugDumpParams () 를 사용하는 것입니다 . 준비된 쿼리에 값을 바인딩 한 후 언제라도이를 실행할 수 있습니다 ( execute()문이 필요 없음 ).

준비된 문장을 작성하지는 않지만 매개 변수를 표시합니다.


2
유일한 문제는 디버그를 '에코 잉'하지 않고 내부에 저장하는 대신 디버그를 출력한다는 것입니다. 이런 식으로 기록 할 수 없습니다.
Ricardo Martins

3
출력 버퍼링 (ob_start () ...)을 사용하여 출력을 저장하고 기록 할 수 있습니다.
Cranio

bugs.php.net/bug.php?id=52384은 늦게 값 : 비트를 볼 수 있습니다 7.1에서 수정 만의 PHP
샌더 프랜트

12

오래된 게시물이지만 아마도 누군가 유용 할 것입니다.

function pdo_sql_debug($sql,$placeholders){
    foreach($placeholders as $k => $v){
        $sql = preg_replace('/:'.$k.'/',"'".$v."'",$sql);
    }
    return $sql;
}

1
숫자 매개 변수를 처리 할 수있는 비슷한 함수에 대해서는 내 답변을 참조하십시오 (php.net의 주석 작성자에게 감사드립니다).
Matt Browne

9

다음은 php.net의 "Mark"에 의해 주석에서 수정 된 효과적인 SQL이 무엇인지 확인하는 함수입니다 .

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;
}

왜 "Mark"가 $ k 전에 콜론을 사용 str_replace(":$k" ....합니까? 연관 인덱스는 이미 $ params 배열에 있습니다.
Alan

좋은 질문 ...이 설명 할 수 있습니다 : stackoverflow.com/questions/9778887/… . 개인적으로 나는이 기능을 사용하여 Doctrine 쿼리를 디버깅했으며 Doctrine은 명명 된 매개 변수가 아닌 숫자를 사용한다고 생각 하므로이 문제를 알지 못했습니다. 콜론을 사용하거나 사용하지 않고 작동하도록 함수를 업데이트했습니다.
Matt Browne

이 솔루션은 :name_long로 대체 됩니다 :name. 적어도 :name앞에 오는 경우 :name_long. MySQL에서 준비한 명령문은이를 올바르게 처리 할 수 ​​있으므로 혼동하지 마십시오.
Zim84

8

아니요. PDO 쿼리는 클라이언트 쪽에서 준비되지 않았습니다. PDO는 단순히 SQL 쿼리 및 매개 변수를 데이터베이스 서버로 보냅니다. 데이터베이스 (의 대체를 무엇이다 ?'들). 두 가지 옵션이 있습니다.

  • DB의 로깅 기능을 사용하십시오 (그러나 그럼에도 Postgres에서는 적어도 두 개의 별도 명령문 (예 : "최종이 아님"으로 표시됨))
  • SQL 쿼리와 매개 변수를 출력하고 직접 조각하십시오.

DB의 로그를 확인하려고 생각하지 않았습니다. MySQL 디렉토리에서 파고 있는데 로그 파일이 보이지 않지만 로깅은 어딘가에서 켜야하는 옵션 일 수 있습니다.
Nathan Long

예, 전원을 켜야합니다. 구체적인 내용을 모르지만 기본적으로 모든 쿼리를 기록하지는 않습니다.
ryeguy

5

check error logs 이외의 에러 표시에 대해서는 거의 언급되지 않았지만 다소 유용한 기능이 있습니다.

<?php
/* Provoke an error -- bogus SQL syntax */
$stmt = $dbh->prepare('bogus sql');
if (!$stmt) {
    echo "\PDO::errorInfo():\n";
    print_r($dbh->errorInfo());
}
?>

( 소스 링크 )

이 코드는 예외 메시지 또는 다른 종류의 오류 처리로 사용되도록 수정 될 수 있음이 분명합니다


2
이것은 잘못된 길입니다. PDO는이 코드를 쓸모 없게 만들 정도로 똑똑합니다. 오류에 대한 예외를 throw하도록 지시하십시오. PHP는 이 제한된 함수보다 나머지를 더 잘 수행합니다 . 또한, 제발 , 직접 브라우저에 모든 오류를 인쇄하지 배웁니다. 더 좋은 방법이 있습니다.
당신의 상식

3
그것은 공식 문서이며, 물론 프로덕션에서 아무도 그 오류를 인쇄하지 않을 것입니다. 다시 공식 사이트 (php.net)의 예입니다. 코드 예 아래의 링크를 참조하십시오. 그리고 PDO 인스턴스화 내에서 추가 매개 변수 $ db-> setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION)를 사용하는 것이 훨씬 더 좋지만 불행히도 해당 코드에 액세스 할 수 없었습니다.
Zippp

4

예를 들어 다음 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,
));

이제 다음과 같은 배열을 정의하여 실행 된 쿼리를 얻을 수 있습니다.

$assoc=array(
  ':val1'=>$val1,
  ':val2'=>$val2,
  ':val3'=>$val3,
);
$exQuery=str_replace(array_keys($assoc), array_values($assoc), $query);
echo $exQuery;

1
나를 위해 일했다. 두 번째 코드 샘플에서 실수 ));가 있습니다 );.
Jasom Dotnet

2

인터넷 검색 나는 이것을 수용 가능한 해결책으로 찾았다. PDO 대신 다른 클래스가 사용되며 PDO 함수는 매직 함수 호출을 통해 호출됩니다. 이것이 심각한 성능 문제를 일으키는 지 확실하지 않습니다. 그러나 합리적인 로깅 기능이 PDO에 추가 될 때까지 사용할 수 있습니다.

따라서이 스레드 에 따라 PDO 연결에 대한 래퍼를 작성하여 오류가 발생하면 예외를 기록하고 throw 할 수 있습니다.

다음은 간단한 예입니다.

class LoggedPDOSTatement extends PDOStatement    {

function execute ($array)    {
    parent::execute ($array);
    $errors = parent::errorInfo();
    if ($errors[0] != '00000'):
        throw new Exception ($errors[2]);
    endif;
  }

}

따라서 PDOStatement 대신 해당 클래스를 사용할 수 있습니다.

$this->db->setAttribute (PDO::ATTR_STATEMENT_CLASS, array ('LoggedPDOStatement', array()));

여기에 언급 된 PDO 데코레이터 구현 :

class LoggedPDOStatement    {

function __construct ($stmt)    {
    $this->stmt = $stmt;
}

function execute ($params = null)    {
    $result = $this->stmt->execute ($params); 
    if ($this->stmt->errorCode() != PDO::ERR_NONE):
        $errors = $this->stmt->errorInfo();
        $this->paint ($errors[2]);
    endif;
    return $result;
}

function bindValue ($key, $value)    {
    $this->values[$key] = $value;    
    return $this->stmt->bindValue ($key, $value);
}

function paint ($message = false)    {
    echo '<pre>';
    echo '<table cellpadding="5px">';
    echo '<tr><td colspan="2">Message: ' . $message . '</td></tr>';
    echo '<tr><td colspan="2">Query: ' . $this->stmt->queryString . '</td></tr>';
    if (count ($this->values) > 0):
    foreach ($this->values as $key => $value):
    echo '<tr><th align="left" style="background-color: #ccc;">' . $key . '</th><td>' . $value . '</td></tr>';
    endforeach;
    endif;
    echo '</table>';
    echo '</pre>';
}

function __call ($method, $params)    {
    return call_user_func_array (array ($this->stmt, $method), $params); 
}

}

2

WAMP 에서 MySQL을 로그하려면 my.ini를 편집해야합니다 (예 : wamp \ bin \ mysql \ mysql5.6.17 \ my.ini)

다음에 추가하십시오 [mysqld].

general_log = 1
general_log_file="c:\\tmp\\mysql.log"

1

다음은 "해결 된"매개 변수를 사용하여 SQL 쿼리를 반환하도록 만든 함수입니다.

function paramToString($query, $parameters) {
    if(!empty($parameters)) {
        foreach($parameters as $key => $value) {
            preg_match('/(\?(?!=))/i', $query, $match, PREG_OFFSET_CAPTURE);
            $query = substr_replace($query, $value, $match[0][1], 1);
        }
    }
    return $query;
    $query = "SELECT email FROM table WHERE id = ? AND username = ?";
    $values = [1, 'Super'];

    echo paramToString($query, $values);

이런 식으로 실행한다고 가정하면

$values = array(1, 'SomeUsername');
$smth->execute($values);

이 함수는 쿼리에 따옴표를 추가하지 않지만 나를 위해 일합니다.


0

디버깅 목적으로 PDO 면제를 잡기 위해 솔루션에 가지고있는 문제는 PDO 면제 (duh) 만 잡았지만 PHP 오류로 등록 된 구문 오류를 포착하지 않았다는 것입니다 (왜 그런지 확실하지 않지만 " 왜 "솔루션과 관련이 없습니다). 모든 PDO 호출은 모든 테이블과의 모든 상호 작용을 위해 확장 된 단일 테이블 모델 클래스에서 온 것입니다 ... 오류는 내 실행 호출이있는 PHP 코드 줄을 등록하기 때문에 코드를 디버깅하려고 할 때의 복잡한 일 전화를 받았지만 실제로 어디에서 왔는지는 말하지 않았습니다. 이 문제를 해결하기 위해 다음 코드를 사용했습니다.

/**
 * Executes a line of sql with PDO.
 * 
 * @param string $sql
 * @param array $params
 */
class TableModel{
    var $_db; //PDO connection
    var $_query; //PDO query

    function execute($sql, $params) { 
        //we're saving this as a global, so it's available to the error handler
        global $_tm;
        //setting these so they're available to the error handler as well
        $this->_sql = $sql;
        $this->_paramArray = $params;            

        $this->_db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $this->_query = $this->_db->prepare($sql);

        try {
            //set a custom error handler for pdo to catch any php errors
            set_error_handler('pdoErrorHandler');

            //save the table model object to make it available to the pdoErrorHandler
            $_tm = $this;
            $this->_query->execute($params);

            //now we restore the normal error handler
            restore_error_handler();
        } catch (Exception $ex) {
            pdoErrorHandler();
            return false;
        }            
    }
}

따라서 위의 코드는 PDO 예외와 PHP 구문 오류를 모두 포착하여 동일한 방식으로 처리합니다. 내 오류 처리기는 다음과 같습니다.

function pdoErrorHandler() {
    //get all the stuff that we set in the table model
    global $_tm;
    $sql = $_tm->_sql;
    $params = $_tm->_params;
    $query = $tm->_query;

    $message = 'PDO error: ' . $sql . ' (' . implode(', ', $params) . ") \n";

    //get trace info, so we can know where the sql call originated from
    ob_start();
    debug_backtrace(); //I have a custom method here that parses debug backtrace, but this will work as well
    $trace = ob_get_clean();

    //log the error in a civilized manner
    error_log($message);

    if(admin(){
        //print error to screen based on your environment, logged in credentials, etc.
        print_r($message);
    }
}

테이블 모델을 전역 변수로 설정하는 것보다 내 오류 처리기에 관련 정보를 얻는 방법에 대한 더 나은 아이디어가 있다면 누구나 듣고 코드를 편집하게되어 기쁩니다.


0

이 코드는 저에게 효과적입니다.

echo str_replace(array_keys($data), array_values($data), $query->queryString);

$ data와 $ query를 당신의 이름으로 바꾸는 것을 잊지 마십시오


0

이 클래스를 사용하여 PDO를 디버깅합니다 ( Log4PHP 사용 )

<?php

/**
 * Extends PDO and logs all queries that are executed and how long
 * they take, including queries issued via prepared statements
 */
class LoggedPDO extends PDO
{

    public static $log = array();

    public function __construct($dsn, $username = null, $password = null, $options = null)
    {
        parent::__construct($dsn, $username, $password, $options);
    }

    public function query($query)
    {
        $result = parent::query($query);
        return $result;
    }

    /**
     * @return LoggedPDOStatement
     */
    public function prepare($statement, $options = NULL)
    {
        if (!$options) {
            $options = array();
        }
        return new \LoggedPDOStatement(parent::prepare($statement, $options));
    }
}

/**
 * PDOStatement decorator that logs when a PDOStatement is
 * executed, and the time it took to run
 * @see LoggedPDO
 */
class LoggedPDOStatement
{

    /**
     * The PDOStatement we decorate
     */
    private $statement;
    protected $_debugValues = null;

    public function __construct(PDOStatement $statement)
    {
        $this->statement = $statement;
    }

    public function getLogger()
    {
        return \Logger::getLogger('PDO sql');
    }

    /**
     * When execute is called record the time it takes and
     * then log the query
     * @return PDO result set
     */
    public function execute(array $params = array())
    {
        $start = microtime(true);
        if (empty($params)) {
            $result = $this->statement->execute();
        } else {
            foreach ($params as $key => $value) {
                $this->_debugValues[$key] = $value;
            }
            $result = $this->statement->execute($params);
        }

        $this->getLogger()->debug($this->_debugQuery());

        $time = microtime(true) - $start;
        $ar = (int) $this->statement->rowCount();
        $this->getLogger()->debug('Affected rows: ' . $ar . ' Query took: ' . round($time * 1000, 3) . ' ms');
        return $result;
    }

    public function bindValue($parameter, $value, $data_type = false)
    {
        $this->_debugValues[$parameter] = $value;
        return $this->statement->bindValue($parameter, $value, $data_type);
    }

    public function _debugQuery($replaced = true)
    {
        $q = $this->statement->queryString;

        if (!$replaced) {
            return $q;
        }

        return preg_replace_callback('/:([0-9a-z_]+)/i', array($this, '_debugReplace'), $q);
    }

    protected function _debugReplace($m)
    {
        $v = $this->_debugValues[$m[0]];

        if ($v === null) {
            return "NULL";
        }
        if (!is_numeric($v)) {
            $v = str_replace("'", "''", $v);
        }

        return "'" . $v . "'";
    }

    /**
     * Other than execute pass all other calls to the PDOStatement object
     * @param string $function_name
     * @param array $parameters arguments
     */
    public function __call($function_name, $parameters)
    {
        return call_user_func_array(array($this->statement, $function_name), $parameters);
    }
}

0

정확히 여기에 현대 Composer로드 프로젝트 / 저장소를 만들었습니다.

pdo-debug

프로젝트의 GitHub 홈을 여기 에서 찾으십시오 ( 여기 에서 설명 하는 블로그 게시물 참조) . composer.json에 추가 할 한 줄을 다음과 같이 사용할 수 있습니다.

echo debugPDO($sql, $parameters);

$ sql은 원시 SQL 문이고 $ parameters는 매개 변수의 배열입니다. 키는 자리 표시 자 이름 ( ": user_id") 또는 명명되지 않은 매개 변수의 번호 ( "?")이며 값은 ..입니다. 값.

논리 :이 스크립트는 단순히 매개 변수를 등급 화하고 제공된 SQL 문자열로 대체합니다. 사용 사례의 99 %에 대해 매우 간단하지만 매우 효과적입니다. 참고 : 이것은 실제 PDO 디버깅이 아닌 기본 에뮬레이션입니다 (PHP는 원시 SQL과 매개 변수를 MySQL 서버로 분리하여 전송할 수 없으므로).

StackOverflow 스레드의 bigwebguyMike 에게 감사의 말 을 전합니다. 기본적으로이 스크립트 뒤의 전체 주요 기능을 작성하기 위해 PDO에서 원시 SQL 쿼리 문자열을 가져옵니다 . 커요!


0

우분투에서 PDO MySQL 데이터베이스 쿼리를 디버깅하는 방법

TL; DR 모든 쿼리를 기록하고 mysql 로그를 마무리하십시오.

이 지침은 Ubuntu 14.04를 설치하기위한 것입니다. lsb_release -a버전을 얻으려면 명령 을 발행 하십시오. 설치가 다를 수 있습니다.

mysql에서 로깅 켜기

  1. 개발자 서버 cmd 줄로 이동
  2. 디렉토리를 변경하십시오 cd /etc/mysql. 라는 파일이 표시되어야합니다 my.cnf. 이것이 우리가 바꿀 파일입니다.
  3. 을 입력하여 올바른 위치에 있는지 확인하십시오 cat my.cnf | grep general_log. my.cnf파일 이 필터링 됩니다. #general_log_file = /var/log/mysql/mysql.log&&의 두 항목이 표시 #general_log = 1됩니다.
  4. 이 두 줄의 주석을 해제하고 선택한 편집기를 통해 저장하십시오.
  5. mysql을 다시 시작하십시오 : sudo service mysql restart.
  6. 웹 서버도 다시 시작해야 할 수도 있습니다. (내가 사용한 순서를 기억할 수 없다). 내 설치의 경우 nginx sudo service nginx restart입니다.

잘 하셨어요! 모두 준비되었습니다. 이제 앱에서 실시간으로 수행하는 PDO 쿼리를 볼 수 있도록 로그 파일을 마무리하기 만하면됩니다.

로그를 조정하여 쿼리를 확인하십시오.

이 cmd를 입력하십시오 tail -f /var/log/mysql/mysql.log.

출력 결과는 다음과 같습니다.

73 Connect  xyz@localhost on your_db
73 Query    SET NAMES utf8mb4
74 Connect  xyz@localhost on your_db
75 Connect  xyz@localhost on your_db
74 Quit 
75 Prepare  SELECT email FROM customer WHERE email=? LIMIT ?
75 Execute  SELECT email FROM customer WHERE email='a@b.co' LIMIT 5
75 Close stmt   
75 Quit 
73 Quit 

로그를 계속해서 추적하는 한 앱에서 새로 만든 모든 쿼리가 자동으로 표시됩니다 . 꼬리를 나가려면를 누르십시오 cmd/ctrl c.

노트

  1. 주의 :이 로그 파일은 커질 수 있습니다. 나는 이것을 dev 서버에서만 실행하고 있습니다.
  2. 로그 파일이 너무 커 집니까? 잘립니다. 즉, 파일은 유지되지만 내용은 삭제됩니다. truncate --size 0 mysql.log.
  3. 로그 파일에 mysql 연결이 나열되어 있는지 확인하십시오. 나는 그중 하나가 내가 전환하고있는 레거시 mysqli 코드에서 온 것임을 알고있다. 세 번째는 새로운 PDO 연결입니다. 그러나 두 번째 곳의 출처는 확실하지 않습니다. 그것을 찾는 빠른 방법을 알고 있다면 알려주십시오.

신용 및 감사

우분투에서 이것을 알아낼 수있는 위의 Nathan Long의 답변에 대해 큰 소리로 외쳤다 . 또한 이 솔루션으로 이어지는 Nathan의 게시물에 대한 그의 의견에 대해 dikirill 합니다.

당신을 사랑합니다


0

데비안 NGINX 환경에서 나는 다음을 수행했습니다.

고토 /etc/mysql/mysql.conf.d편집 mysqld.cnf찾을 경우 log-error = /var/log/mysql/error.log다음 두 줄이 노호 추가합니다.

general_log_file        = /var/log/mysql/mysql.log
general_log             = 1

로그가 고토 볼 /var/log/mysqltail -f mysql.log

프로덕션 환경에있는 경우 디버깅을 마치면 mysql.log이 로그 파일이 빠르게 커지고 크기가 커질 수 있으므로 이러한 줄을 주석 처리해야합니다 .


모든 사람이 mysql을 사용하는 것은 아닙니다.
공포의 세미콜론
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.