PHPでmysqliを使用してプリペアドステートメントを使用する方法を学習しています。通常、クエリで問題が発生した場合は、画面にエコーして、次のように表示されます。最初のステップ。
プリペアドステートメントでそれを行うにはどうすればよいですか?
変数が代入された後のSQLステートメントを見たいのですが。
プリペアドステートメントの使用:
PHP側にはSQLクエリの「構築」がないため、実際にそのクエリを取得する方法はありません。
つまり、SQLクエリを表示する場合は、プリペアドステートメントではなくSQLクエリを使用する必要があります。
Mysql_stmt_prepare()およびmysql_stmt_execute()C API関数で実行される準備済みステートメントの場合、サーバーは準備行と実行行を一般クエリログに書き込み、ステートメントがいつ準備され実行されるかを確認できるようにします。
[...]サーバーは次の行を一般的なクエリログに書き込みます。
準備[1] SELECT?
[1] SELECT3を実行します
したがって、デバッグの目的で、 一般ログ をアクティブにし、そのファイルを監視します。
編集:ああ、質問には[mysqli]タグがあります...それを完全に見落としていました。
ステートメントがまったく実行されない場合、途中でエラーが発生していないことを(ダブル/トリプル)チェックしましたか?
echo "<pre>Debug: start</pre>\n";
$mysqli = new mysqli('localhost', 'localonly', 'localonly', 'test');
if ($mysqli->connect_error) {
die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
}
$result = $mysqli->query('CREATE TEMPORARY TABLE foo (id int auto_increment, x int, primary key(id))');
if ( false=== $result) {
die('error : '. $mysqli->error);
}
$stmt = $mysqli->prepare('INSERT INTO foo (x) VALUES (?)');
if ( false===$stmt ) {
die ('prepare() failed: ' . $mysqli->error);
}
$result = $stmt->bind_param('i', $x);
if ( false===$result ) {
die('bind_param() failed');
}
$x = 1;
$result = $stmt->execute();
if ( false===$result ) {
die('execute() failed: '.$stmt->error);
}
echo "<pre>Debug: end</pre>\n";
私は通常、パラメータを使用して準備されたSQLをデバッグする必要があるときにこれを行います。
準備と実行の例:
$sql = "SELECT VAL1, VAL2 FROM TABLE(?, '?', '?', '?', '?', ?, '?', '?', '?')";
$prep = ibase_prepare( $sql ) or die("Error");
$query = ibase_execute($prep, $param1, $param2, .....) or $err = true;
^^^^^^^^^^^^^^^^^^^^^^^
文の結果のSQLをデバッグする簡単な方法は次のとおりです。
printf( str_replace('?', '%s', $sql), $param1, $param2, ....);
^^^^^^^^^^^^^^^^^^^^^^
準備したSQL文字列の?
を1つの%s
に置き換えて、1つのprintfを実行するだけで済みます。 printf
は、すべてを1つの文字列として解釈し、各パラメーターを、置き換えられた各%s
に配置するものと見なします。
最近、このプロジェクトを更新して、composer統合、単体テストを含め、参照による引数の受け入れをより適切に処理できるようにしました(これには、php 5.6への更新が必要です)。
デフォルトのmysqli
クラスと_mysqli_stmt
_クラスを拡張するクラスのセットを作成して、潜在的なクエリ文字列のレンディションを表示できるようにしました。これにより、探しているものが提供されます。
https://github.com/noahheck/E_mysqli
これは、クエリ文字列をprepare()
するとカスタムの_mysqli_stmt
_オブジェクトを返す通常のmysqli
オブジェクトの(近い)ドロップイン置換です。パラメータをバインドした後、_E_mysqli
_を使用すると、結果のクエリ文字列をstmt
オブジェクトの新しいプロパティとして表示できます。
_$mysqli = new E_mysqli($dbHost, $dbUser, $dbPass, $dbName);
$query = "INSERT INTO registration SET name = ?, email = ?";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("ss", $_POST['name'], $_POST['email']);
$stmt->execute();
echo $stmt->fullQuery;
_
結果は次のようになります。
_INSERT INTO registration SET name = 'John Doe', email = '[email protected]'
_
この拡張機能の使用にはいくつかの注意点があります(githubプロジェクトのREADME)で説明されています)が、アプリケーションの厄介な領域のトラブルシューティングや、手続き型からオブジェクト指向スタイルへの移行のために、これはほとんどのユーザーにとってのヘルプのレベル。
Githubプロジェクトで概説したように、私はmysqli
拡張機能を使用した実際の経験がありません。このプロジェクトは、姉妹プロジェクトのユーザーの要求に応じて作成されたため、フィードバックを提供できます。これを本番環境で使用している開発者からの感謝です。
免責事項-私が言ったように、私はこの拡張を行いました。
Pascal MARTIN(+1)に同意するので、デバッグのための別の手法を提案します:var_dump()
またはステートメントに挿入するすべての変数をログに記録します。そうすれば、データが間違っているかどうかを判断できます。論理的に間違ったSQL。
Lottip のようなツールを使用できます。アイデアはMySQLプロキシのように機能します。 MySQLパケットを解析し、クエリとそのパラメータを抽出するため、プリペアドステートメントとその内容を確認できます。