PHPを使用してMySQLを含むアプリケーションを開発する場合、一部の開発者はMySQL_INFO()またはMySQLI_INFO()を使用して、バッチ挿入、更新、または削除記述に影響を受ける行数など、特定のSQL操作を実行した後に補足情報を取得します。ただし、返されたデータが不正確であることがわかり、一部の操作の直後に誤った文字列または空の文字列を返すことがある場合があります。この「信頼できない」振る舞いで何が起こっているのですか?この記事は、その動作の原則から始まり、理由を分析し、対処戦略を提供します。
mysql_info()は、主に、次のような特定の非選択ステートメントを実行した後、実行ステータスの簡単な説明を取得するために使用されます。
$link = mysqli_connect("localhost", "user", "pass", "testdb");
mysqli_query($link, "UPDATE users SET status = 1 WHERE id < 100");
echo mysqli_info($link);
返品コンテンツは次のとおりです。
Rows matched: 100 Changed: 100 Warnings: 0
この出力情報は、一致する行の数と変更の数を決定するなど、バッチ操作をデバッグする場合に非常に便利です。ただし、これは、基礎となるMySQLによって返されるステータス情報に依存します。
すべての非選択操作が情報情報を生成するわけではなく、公式のMySQLドキュメントは、次のステートメントタイプのみがこの情報を提供できることを明確に述べています。
INSERTINGに...選択...
アップデート
消去
データをロードします
特にサブクエリを介してデータが挿入されないシナリオでは、通常の挿入、交換などのようなステートメントは、多くの場合、情報キャッシュを入力しません。
PHPで使用されるMySQLクライアントライブラリ(LIBMYSQLまたはMYSQLND)も情報の取得に影響します。 MySQLND(MySQLネイティブドライバー)を使用する場合、 MySQLI_INFO()によって返されるコンテンツはより信頼性が高くなります。 libmysqlの場合、一部の情報を記録または返して遅延しない場合があります。
複数のSQLステートメントが接続内で実行されている場合(たとえば、バッチ処理)、 mysqli_info()は最後のステートメントの情報情報のみを返します。つまり、
mysqli_query($link, "UPDATE table1 SET name = 'A'; UPDATE table2 SET name = 'B';");
echo mysqli_info($link); // 戻るだけです table2 実行情報
これにより、多くの開発者は、以前のオペレーションが実行されていないか、効果がないと誤って信じています。
さまざまなMySQL Serverバージョンは、情報コンテンツを返すことに違いがあります。たとえば、古いバージョンは一致した行や警告をカウントしない場合があります。または、間違った数の行を返すバグがあります。さらに、いくつかのパフォーマンス最適化オプションが有効になっている場合、いくつかの統計ロジックがスキップされる場合があります。
PHP環境でMySQLNDドライバーが有効になっていることを確認してください。次のように確認できます。
if (function_exists('mysqli_get_client_stats')) {
echo "mysqlnd 有効になっています";
}
MySqlndは、より包括的で標準化された情報サポートを提供します。これは、libmysqlよりも生産環境に推奨されます。
複数のステートメント(multi_query)の情報の返品に依存しないでください。各ステートメントは個別に実行する必要があり、対応する情報情報をすぐに読み取って、後続の声明によって上書きされないようにする必要があります。
mysqli_query($link, "DELETE FROM logs WHERE created_at < NOW() - INTERVAL 30 DAY");
$logInfo = mysqli_info($link);
echo "ログクリーニング結果:" . $logInfo;
いくつかの重要なSQL操作については、 mysql_info()によって返されたテキストの説明に完全に依存するのではなく、ビジネスロジックに基づいて追加のクエリまたはロギングを実行して検証することをお勧めします。たとえば、行数の差をクリーンアップしてから、トランザクション制御を通じて正確な実行を確保します。
変更されたことに注意してください:0は、 SQLが正常に実行されていないことを意味するものではなく、データ自体が変更されていない可能性があります(たとえば、同じ値に更新されます)。このシナリオはアップデートで非常に一般的であり、また、行が一致しているが変更された理由を説明します:0 。
より効率的にデバッグして記録するために、情報情報を書き込み、次の方法を使用してログに記録したり、バックグラウンドインターフェイスに表示したりできます。
$sql = "UPDATE users SET status = 0 WHERE active = 0";
mysqli_query($link, $sql);
file_put_contents("/var/log/mysql_ops.log", date('Y-m-d H:i:s') . " " . $sql . " => " . mysqli_info($link) . "\n", FILE_APPEND);
これらの操作レコードは、インターフェイスを介してリモート監視システムに送信することもできます。