この記事では、PHP のプリペアド ステートメントとトランザクションについて紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。
#PHP で学ぶ PDO 操作 (2) ステートメントとトランザクションの前処理
今日の記事では、簡単な使い方を学びましょうPDO におけるプリペアドステートメントやトランザクションの操作はすべて PDO オブジェクトの下での操作であり、複雑ではなく、単純なアプリケーションを簡単に実装できます。しかし、みんなフレームを使っていることがほとんどで、手書きする機会はほとんどありません。
プリプロセスされたステートメント関数
準備されたステートメントは、実行するステートメントを準備し、PDOStatement オブジェクトを返します。通常、このステートメントを実行するには、PDOStatement オブジェクトのexecute() メソッドを使用します。なぜ前処理と呼ばれるのでしょうか?これにより、このステートメントを複数回呼び出して、ステートメント内のフィールド条件をプレースホルダーに置き換えることができるためです。 PDO オブジェクトを直接使用する query() または exec() と比較して、前処理がより効率的であり、クライアント/サーバーがクエリとメタ情報をキャッシュできるようになります。もちろん、より重要な点は、プレースホルダーの適用により、基本的な SQL インジェクション攻撃を効果的に防止できるということです。SQL ステートメントに手動で引用符を追加する必要はなく、前処理によってこの問題を直接解決できます。これは誰でも学習できると思います。過去の知識は次のとおりです。これは、面接中によく見られる質問の 1 つです。
// 使用 :name 形式创建一个只进游标的 PDOStatement 对象
$stmt = $pdo->prepare("select * from zyblog_test_user where username = :username", [PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY]);
var_dump($stmt);
// object(PDOStatement)#2 (1) {
// ["queryString"]=>
// string(57) "select * from zyblog_test_user where username = :username"
// }
$stmt->execute([':username' => 'aaa']);
$aUser = $stmt->fetchAll();
$stmt->execute([':username' => 'bbb']);
$bUser = $stmt->fetchAll();
var_dump($aUser);
// array(1) {
// [0]=>
// array(8) {
// ["id"]=>
// string(1) "1"
// [0]=>
// string(1) "1"
// ["username"]=>
// string(3) "aaa"
// ……
var_dump($bUser);
// array(1) {
// [0]=>
// array(8) {
// ["id"]=>
// string(1) "2"
// [0]=>
// string(1) "2"
// ["username"]=>
// string(3) "bbb"
// ……
ログイン後にコピー
prepare() メソッドの最初のパラメータは、実行する必要がある SQL ステートメントです。このコードでは、:xxx の形式でプレースホルダを使用しているため、prepare() メソッドを呼び出すときに、 PDOStatement オブジェクトの use() メソッドを実行するときに、プレースホルダー値を指定する必要があります。コードでは、この SQL ステートメントを使用して、異なるプレースホルダーの内容を置き換えることにより 2 つのクエリを実装します。
prepare() メソッドの 2 番目のパラメーターは、返された PDOStatement オブジェクトに設定されたプロパティです。一般的な使用法は次のとおりです。 PDO::ATTR_CURSOR を PDO::CURSOR_SCROLL に設定すると、スクロール可能なカーソルが取得されます。
一部のドライバーにはドライバー レベルのオプションがあり、これは準備中に設定されます。 PDO::ATTR_CURSOR はデータベース カーソルを設定する型で、PDO::CURSOR_FWDONLY はカーソルに入るだけの PDOStatement オブジェクトを作成することを意味します。このカーソルは PHP で最も高速かつ最も一般的なデータ アクセス モードであるため、これがデフォルトのカーソル オプションです。データベースカーソルに関する知識については、該当する内容をご自身でご確認ください。
さらに、PDOStatement は、bindParam() メソッドを通じてプレースホルダー データをバインドすることもできます。PDOStatement オブジェクトに関連する次の記事で引き続き学習していきます。
次に、? プレースホルダーを使用してクエリを実装する方法を見てみましょう。? プレースホルダーは、バインド時に添字の形式でバインドされます。
// 使用 ? 形式创建一个只进游标的 PDOStatement 对象
$stmt = $pdo->prepare("select * from zyblog_test_user where username = ?", [PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY]);
$stmt->execute(['aaa']);
$aUser = $stmt->fetchAll();
var_dump($aUser);
// array(1) {
// [0]=>
// array(8) {
// ["id"]=>
// string(1) "1"
// [0]=>
// string(1) "1"
// ["username"]=>
// string(3) "aaa"
// ……
ログイン後にコピー
もちろん、この種のプリコンパイル済みステートメントはクエリ ステートメントに限定されず、追加、削除、変更が可能で、プレースホルダーもサポートしています。 PHP でデータベースを操作するためのプリペアド ステートメント この記事には詳細な例が記載されています。
トランザクション機能
誰もがトランザクションについて一定の理解を持っている必要があるため、ここでは特定の概念を紹介しません。PDO のトランザクションについてだけ見てみましょう。達成。まず、トランザクションがない場合に何が起こるかを見てみましょう。
$pdo->exec("insert into tran_innodb (name, age) values ('Joe', 12)"); // 成功插入
$pdo->exec("insert into tran_innodb2 (name, age) values ('Joe', 12)"); // 报错停止整个PHP脚本执行
// Fatal error: Uncaught PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'blog_test.tran_innodb2' doesn't exist
ログイン後にコピー
これら 2 つのテーブルを同時に更新する必要があるが、2 番目のステートメントでエラーが報告されたとします。トランザクションがない場合、最初のデータは正常に挿入されますが、これは必要な結果ではありません。現時点では、2 つのテーブルを同時に成功または失敗させることができるように、トランザクション機能の助けが必要です。
try {
// 开始事务
$pdo->beginTransaction();
$pdo->exec("insert into tran_innodb (name, age) values ('Joe', 12)");
$pdo->exec("insert into tran_innodb2 (name, age) values ('Joe', 12)"); // 不存在的表
// 提交事务
$pdo->commit();
} catch (Exception $e) {
// 回滚事务
$pdo->rollBack();
// 输出报错信息
echo "Failed: " . $e->getMessage(), PHP_EOL;
// Failed: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'blog_test.tran_innodb2' doesn't exist
}
ログイン後にコピー
最初のメソッドは beginTransaction() メソッドで、データベースの自動送信をオフにしてトランザクションを開始するために使用されます。このメソッドの後は、commit() または rollBack( )方法の事務です。
commit() メソッドは、操作中に事故がなかった場合、beginTransaction() の後にすべてのデータ操作をパッケージ化して送信します。
rollBack() はデータをロールバックします。beginTransaction() の後のステートメントまたはコードに問題がある場合、前のデータ操作がロールバックされ、beginTransaction() の後のすべてのステートメントが成功するか、または成功するかどうかが確認されます。失敗します。
これら 3 つの単純な関数により、トランザクション操作全体が完了します。トランザクションの詳細な研究については、将来 MySQL を詳しく学習するときに説明します。ここで注意する必要があるのは、PDO オブジェクトで例外をスローするエラー モードを指定するのが最善であるということです。エラー モードが指定されていない場合、トランザクション内のエラーは直接報告されず、エラー コードが返されます。エラー コードを使用して、コミットするかロールバックするかを決定する必要があります。これは、例外メカニズムよりもはるかに簡潔で直感的ではありません。
总结
我们简单的梳理并学习了一下 PDO 中的预处理和事务相关的知识,接下来就要进入 PDOStatement 对象相关内容的学习。PDOStatement 对象就是 PDO 的预处理对象,也就是在日常开发中我们会接触到的最多的数据操作对象。这块可是重点内容,大家可不能松懈了哦!
测试代码:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202008/source/PHP%E4%B8%AD%E7%9A%84PDO%E6%93%8D%E4%BD%9C%E5%AD%A6%E4%B9%A0%EF%BC%88%E4%BA%8C%EF%BC%89%E9%A2%84%E5%A4%84%E7%90%86%E8%AF%AD%E5%8F%A5%E5%8F%8A%E4%BA%8B%E5%8A%A1.php
ログイン後にコピー
推荐学习:php视频教程
以上が1 分で PHP のプリペアドステートメントとトランザクションを理解できますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。