PDOで実行したSQL文をdebugDumpParamsから抽出表示する

投稿者: | 2021年3月9日

PHP 5から PHP 7へ移行して最大の懸案はDB読み書き系。当時から PDO で組んでいたはず、と思い実際ほぼその通りだったのですが、DB書き込み系に PHP 7では古くて使えなくなったスクリプトがいました。 PDO へ書き換えるに当たり、 SQL 文のデバッグ出力が見にくいのがとても不便なので、 debugDumpParams を使い改善出来ないか調べてみました。

PHP 5での書き込み系

mysql_connectによるレコード追加SQLの例を示します。これはブログと同じサーバで運用している Hong Kong Tram Archive と言う日々のトラム画像のデータベースサイトの運用に使われているもので、新規画像の情報をフォト蔵よりAPIでXML取得し、レコードをループで追加しています(INSERT IGNORE として、テーブルに既にあるレコードはスキップする仕様)。

実際にはこのスクリプトを開発サーバで実行、テーブルレコードの差分CSVを本番DBへインポート、が定期更新作業ですが、PHPスクリプトをブラウザから叩いた戻りにSQL文字列を出力させてデバッグ確認としていました。

図1.PHP5 mysql_connectでのデバッグ出力例

図1.PHP5 mysql_connectでのデバッグ出力例

PHP 7の PDO による書き込み系

PHP触るのは数年ぶりですが、PDOでmysql DBへINSERTするひな型は次のように出来ました。

SQLステートメントの入れ物をオブジェクトとして生成し(prepare)、そこへパラメータをバインド(bindParam)して実行(execute)。この一連の動作全体をtry〜catchで囲みエラーハンドリングします。

問題はデバッグ出力をどうするか。SQLステートメントオブジェクトを単純にprint_rしただけでは、空っぽな入れ物が表示されるのみ。

図2.PHP7 PDO print_r出力

図2.PHP7 PDO print_r出力



 

debugDumpParams を知る

debugDumpParams を使えばプリペアドステートメントの情報を直接出力出来るとあり、早速使ってみます。

図3.PHP7 PDO debugDumpParams直接出力

図3.PHP7 PDO debugDumpParams直接出力

これをブラウザソースで見ると1レコード分は次のように構成されているのが判ります。

実際は数十レコードを処理するのが通例なので、実行後にレコード数をカウントしやすくする意味でも、必要な情報の1レコード1行への整形が必要です。

debugDumpParams を取り込む

debugDumpParamsはあくまで直接出力なので、それをそのまま変数に入れたり整形したりすることは出来ません。それを可能にするためのひと工夫が、先ほどのリファレンスページ下端にありました。その参照元としているのがこちら(Great Tnx!!)。


Output Bufferを使ってdebugDumpParamsの出力を変数へ取り込む関数を定義し、ステートメントオブジェクトを引数に渡します。

 

debugDumpParams を整形

debugDumpParamsの出力のうち欲しいのは上項のブラウザソース出力の2行目の部分ですが、実際には改行されていないようで、行単位での抽出は出来ませんでした。逆に全ては1行であると考えて、パターンマッチングを使った抽出にしてみます。

preg_match関数「Sent SQL:」より以降初回に出現する「Params:」迄の間の中身 を抽出して表示します。

図4.PHP7 PDO debugDumpParamsを正規表現抽出

図4.PHP7 PDO debugDumpParamsを正規表現抽出



これで今まで通りに、INSERT文実行後のデバッグ確認を出来るようになりました。

※ちなみにpreg_match関数で使った正規表現は、html xml タグの中身を取り出す時によく使う手法です。

コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA