PDO veritabanı sorgularını hata ayıklama nasıl?

8 Cevap php

PDO geçmeden önce, ben dizeleri birleştirerek PHP SQL sorguları yarattı. Ben veritabanı sözdizimi hatası var ise, ben sadece son SQL sorgu dizesi yankı olabilir, daha sonra kodun içine geri koymak, kendimi veritabanı üzerinde deneyin, ve ben hata sabit kadar çimdik.

Hazırlanan PDO ifadeleri daha hızlı ve daha iyi ve daha güvenli, ama bir şey beni rahatsız: Bu veritabanına gönderilen gibi ben son sorgu görmek asla. Ben Apache günlüğüne ya da benim özel günlük dosyasında sözdizimi hakkında hataları olsun (bir catch bloğunun içindeki hataları log), ben onları neden sorgu göremiyorum.

Is there a way capture the complete SQL query sent by PDO to the database and log it to a file?

8 Cevap

Looking in the database log

Pascal MARTIN PDO seferde veritabanına tam geçecektir olmadığı doğru olsa da, ryeguy 'nin DB'ın günlük işlevini kullanmak için öneri aslında bana tam sorguyu görmek için izin montajı ve veritabanı tarafından idam gibi.

Here's how: (These instructions are for MySQL on a Windows machine - your mileage may vary)

  • In my.ini, [mysqld] bölümünde, log="C:\Program Files\MySQL\MySQL Server 5.1\data\mysql.log" gibi, bir log komutu eklemek
  • MySQL yeniden başlatın.
  • O dosyada her sorgu oturum başlayacak.

Bu dosya hızlı büyür, bu yüzden silmek ve test bittiğinde günlüğünü kapatmak için emin olacaktır.

Bunu söylemek:

I never see the final query as it's sent to the database

Aslında, hazırlanmış deyimleri kullanırken, there is no such thing as a "final query ":

  • First, a statement is sent to the DB, and prepared there
    • Veritabanı sorgu ayrıştırır ve bunun bir iç temsilini oluşturur
  • And, when you bind variables and execute the statement, only the variables are sent to the database
    • Ve veritabanı deyimi kendi iç gösterimi içine değerleri "enjekte"


So, to answer your question :

Is there a way capture the complete SQL query sent by PDO to the database and log it to a file?

No : as there is no "complete SQL query ", her yerde onu yakalamak için hiçbir yolu yoktur.


The best thing you can do, for debugging purposes, is "re-construct" an "real" SQL query, by injecting the values into the SQL string of the statement.

Ben genellikle ne, bu durumlara tür olduğunu:

  • tutucular ile, ifadesine karşılık SQL kodunu echo
  • ve parametrelerin değerleri görüntülemek için, hemen sonra (or an equivalent) kullanmak var_dump
  • Bu size yürütebilirsiniz herhangi bir "gerçek" sorgu yoksa bile, olası bir hatayı görmek için genellikle yeterlidir.

Hata ayıklama söz konusu olduğunda, bu, büyük değil - ama bu hazırlanan tablolar ve onlar getirmek avantajları fiyat.

Eski bir yazı ama belki birileri bu yararlı bulacaksınız;

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

No PDO sorguları istemci tarafında hazır değildir. PDO sadece veritabanı sunucusuna SQL sorgusu ve parametreleri gönderir. database (? 's) ikamesini yaptığı budur. İki seçeneğiniz var:

  • Lütfen DB'ın günlük işlevini kullanın (ama o zaman bile normalde en az Postgres ile iki ayrı tablo (yani, "nihai değil") olarak gösterilene)
  • Output the SQL query and the paramaters and piece it together yourself

Örneğin bu pdo bildirimde:

$query="insert into tblTest (field1, field2, field3)
values (:val1, :val2, :val3)";
$res=$db->prepare($query);
$res->execute(array(
  ':val1'=>$val1,
  ':val2'=>$val2,
  ':val3'=>$val3,
));

şimdi böyle bir dizi tanımlayarak yürütülen sorgu alabilirsiniz:

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

almost nothing was said about error displaying except check error logs, but there's a rather helpful functionality:

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

(source link)

it is clear that this code can be modified to be used as exception message or any other kind of error handling

İnternet arama Ben kabul edilebilir bir çözüm olarak bu buluyorum. Farklı sınıf yerine PDO ve PDO fonksiyonları kullanılan sihirli bir işlev çağrıları aracılığıyla denir. Ben bu ciddi performans sorunları yaratır emin değilim. Makul bir günlük özelliği PDO eklenir kadar Ama kullanılabilir.

http://www.sitepoint.com/forums/showthread.php?556965-Best-way-to-log-PDO-queries

Burada etkili SQL at "Mark" ile bir yorumun, ne olacağını görmek için bir fonksiyon php.net:

function parms($string,$data) {
    $indexed=$data==array_values($data);
    foreach($data as $k=>$v) {
        if(is_string($v)) $v="'$v'";
        if($indexed) $string=preg_replace('/\?/',$v,$string,1);
        else $string=str_replace(":$k",$v,$string);
    }
    return $string;
}

//    Index Parameters
    $string='INSERT INTO stuff(name,value) VALUES (?,?)';
    $data=array('Fred',23);

//    Named Parameters
    $string='INSERT INTO stuff(name,value) VALUES (:name,:value)';
    $data=array('name'=>'Fred','value'=>23);

print parms($string,$data);