PDO (PHP Data Objects)は、複数のデータベース管理システム(DBMS)との相互作用を統一された方法で相互作用できるデータベースにアクセスするためのインターフェイスです。 PDOを使用する重要な機能は、準備されたステートメントを介してクエリを実行する機能です。このアプローチは、パフォーマンスを改善するだけでなく、SQL注入攻撃を効果的に防止します。
前処理ステートメントの実行は、通常、2つのステップに分割されます。
事前コンパイル:SQLステートメントを使用して、PDOSTATEMENTオブジェクトを生成し、クエリのパラメータープレースホルダーをプリコンパイルします。
実行:プレースホルダーの代わりに実際のデータを使用して、 execute()メソッドを呼び出してクエリを実行します。
<span><span><span class="hljs-comment">// 作成する PDO 例</span></span><span>
</span><span><span class="hljs-variable">$pdo</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">PDO</span></span><span>(</span><span><span class="hljs-string">'mysql:host=localhost;dbname=test'</span></span><span>, </span><span><span class="hljs-string">'root'</span></span><span>, </span><span><span class="hljs-string">''</span></span><span>);
</span><span><span class="hljs-comment">// 事前コンパイルされています SQL 声明</span></span><span>
</span><span><span class="hljs-variable">$stmt</span></span><span> = </span><span><span class="hljs-variable">$pdo</span></span><span>-></span><span><span class="hljs-title function_ invoke__">prepare</span></span><span>(</span><span><span class="hljs-string">"SELECT * FROM users WHERE id = :id"</span></span><span>);
</span><span><span class="hljs-comment">// パラメーターをバインドし、クエリを実行します</span></span><span>
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">execute</span></span><span>([</span><span><span class="hljs-string">'id'</span></span><span> => </span><span><span class="hljs-number">1</span></span><span>]);
</span></span>
execute()を呼び出す前に、パラメーターバインディングの使用方法を理解することが非常に重要です。 PDOは2つの一般的なプレースホルダーを提供します。
名前付きプレースホルダー:など:ID 、コードの可読性と保守性を向上させることができます。
質問マークプレースホルダー:など?、それは位置からパラメーターをバインドします。
<span><span><span class="hljs-comment">// 名前付きプレースホルダーを使用します</span></span><span>
</span><span><span class="hljs-variable">$stmt</span></span><span> = </span><span><span class="hljs-variable">$pdo</span></span><span>-></span><span><span class="hljs-title function_ invoke__">prepare</span></span><span>(</span><span><span class="hljs-string">"SELECT * FROM users WHERE id = :id"</span></span><span>);
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">execute</span></span><span>([</span><span><span class="hljs-string">'id'</span></span><span> => </span><span><span class="hljs-number">1</span></span><span>]);
</span><span><span class="hljs-comment">// 疑問符のプレースホルダーを使用します</span></span><span>
</span><span><span class="hljs-variable">$stmt</span></span><span> = </span><span><span class="hljs-variable">$pdo</span></span><span>-></span><span><span class="hljs-title function_ invoke__">prepare</span></span><span>(</span><span><span class="hljs-string">"SELECT * FROM users WHERE id = ?"</span></span><span>);
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">execute</span></span><span>([</span><span><span class="hljs-number">1</span></span><span>]);
</span></span>
execute()を呼び出す場合、エラー処理は特に重要です。 PDOはデフォルトで警告の形でエラーをスローしますが、その動作はPDO :: ATTR_ERRMODEを設定することにより例外をスローするように変更できます。プログラムの堅牢性を確保するには、エラー処理に例外モードを使用することをお勧めします。
<span><span><span class="hljs-variable">$pdo</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">PDO</span></span><span>(</span><span><span class="hljs-string">'mysql:host=localhost;dbname=test'</span></span><span>, </span><span><span class="hljs-string">'root'</span></span><span>, </span><span><span class="hljs-string">''</span></span><span>);
</span><span><span class="hljs-variable">$pdo</span></span><span>-></span><span><span class="hljs-title function_ invoke__">setAttribute</span></span><span>(PDO::</span><span><span class="hljs-variable constant_">ATTR_ERRMODE</span></span><span>, PDO::</span><span><span class="hljs-variable constant_">ERRMODE_EXCEPTION</span></span><span>);
</span></span>
これにより、実行中にエラーが発生した場合(SQLエラーやパラメーターバインディングの問題など)、PDOはプログラマーがキャッチして処理できる例外をスローします。
<span><span><span class="hljs-keyword">try</span></span><span> {
</span><span><span class="hljs-variable">$stmt</span></span><span> = </span><span><span class="hljs-variable">$pdo</span></span><span>-></span><span><span class="hljs-title function_ invoke__">prepare</span></span><span>(</span><span><span class="hljs-string">"SELECT * FROM users WHERE id = :id"</span></span><span>);
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">execute</span></span><span>([</span><span><span class="hljs-string">'id'</span></span><span> => </span><span><span class="hljs-number">1</span></span><span>]);
} </span><span><span class="hljs-keyword">catch</span></span><span> (PDOException </span><span><span class="hljs-variable">$e</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Error: "</span></span><span> . </span><span><span class="hljs-variable">$e</span></span><span>-></span><span><span class="hljs-title function_ invoke__">getMessage</span></span><span>();
}
</span></span>
execute()メソッドに渡されたパラメーターが、SQLステートメントのデータ型と一致していることを確認してください。たとえば、データベーステーブルのフィールドが整数タイプの場合、バインディングパラメーターの場合、整数タイプのデータも渡す必要があります。
<span><span><span class="hljs-comment">// 間違い:整数の代わりに文字列を渡します</span></span><span>
</span><span><span class="hljs-variable">$stmt</span></span><span> = </span><span><span class="hljs-variable">$pdo</span></span><span>-></span><span><span class="hljs-title function_ invoke__">prepare</span></span><span>(</span><span><span class="hljs-string">"SELECT * FROM users WHERE id = :id"</span></span><span>);
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">execute</span></span><span>([</span><span><span class="hljs-string">'id'</span></span><span> => </span><span><span class="hljs-string">'one'</span></span><span>]);
</span><span><span class="hljs-comment">// 正しい:传递正しい的数据类型</span></span><span>
</span><span><span class="hljs-variable">$stmt</span></span><span> = </span><span><span class="hljs-variable">$pdo</span></span><span>-></span><span><span class="hljs-title function_ invoke__">prepare</span></span><span>(</span><span><span class="hljs-string">"SELECT * FROM users WHERE id = :id"</span></span><span>);
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">execute</span></span><span>([</span><span><span class="hljs-string">'id'</span></span><span> => </span><span><span class="hljs-number">1</span></span><span>]);
</span></span>
バインドされたパラメーターが異なることを除いて、同じSQLステートメントを複数回実行する必要がある場合があります。この場合、 execute()を使用して、異なるパラメーターで各クエリを繰り返し実行できますが、 execute()は実行されるたびに以前のバインディング情報をクリアすることに注意する必要があります。したがって、同じSQLを複数回実行する場合は、毎回パラメーターを再調整することをお勧めします。
<span><span><span class="hljs-variable">$stmt</span></span><span> = </span><span><span class="hljs-variable">$pdo</span></span><span>-></span><span><span class="hljs-title function_ invoke__">prepare</span></span><span>(</span><span><span class="hljs-string">"SELECT * FROM users WHERE age = :age"</span></span><span>);
</span><span><span class="hljs-variable">$ages</span></span><span> = [</span><span><span class="hljs-number">20</span></span><span>, </span><span><span class="hljs-number">30</span></span><span>, </span><span><span class="hljs-number">40</span></span><span>];
</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$ages</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$age</span></span><span>) {
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">execute</span></span><span>([</span><span><span class="hljs-string">'age'</span></span><span> => </span><span><span class="hljs-variable">$age</span></span><span>]);
</span><span><span class="hljs-comment">// 処理結果</span></span><span>
}
</span></span>
execute()メソッドの返品値は、クエリが成功したかどうかを示します。選択したクエリの場合、通常、 FetchまたはFetchallメソッドを使用してクエリ結果を取得する必要があります。
<span><span><span class="hljs-variable">$stmt</span></span><span> = </span><span><span class="hljs-variable">$pdo</span></span><span>-></span><span><span class="hljs-title function_ invoke__">prepare</span></span><span>(</span><span><span class="hljs-string">"SELECT * FROM users WHERE id = :id"</span></span><span>);
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">execute</span></span><span>([</span><span><span class="hljs-string">'id'</span></span><span> => </span><span><span class="hljs-number">1</span></span><span>]);
</span><span><span class="hljs-comment">// シングルラインの結果を取得します</span></span><span>
</span><span><span class="hljs-variable">$result</span></span><span> = </span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">fetch</span></span><span>(PDO::</span><span><span class="hljs-variable constant_">FETCH_ASSOC</span></span><span>);
</span><span><span class="hljs-comment">// すべての結果を取得します</span></span><span>
</span><span><span class="hljs-variable">$results</span></span><span> = </span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">fetchAll</span></span><span>(PDO::</span><span><span class="hljs-variable constant_">FETCH_ASSOC</span></span><span>);
</span></span>
execute()はクエリの結果を自動的に返さないことに注意する必要があります。 SQLステートメントの実行のみを担当しており、実際の結果の取得は、後続のフェッチまたはFetchallを通過する必要があります。
execute()を使用する場合、プログラマーは次の一般的なエラーに遭遇する傾向があります。
パラメータータイプの不一致:SQLのデータ型が、バインドされたパラメーターのデータ型と一致していることを確認します。
パラメーターをバインドするのを忘れました: execute()を実行すると、すべてのプレースホルダーのパラメーターをバインドするのを忘れた場合、エラーを引き起こす可能性があります。 SQLステートメントとexecute()パラメーターが1つずつ対応するかどうかを確認します。
間違ったSQL構文:特にプレースホルダーを使用する場合は、SQL構文が正しいことを確認してください。
同じpdostatementオブジェクトで複数回実行された場合、複数の呼び出しが同じpdostatementオブジェクトで実行された場合、毎回パラメーターを必ず再バインドしてください。
これらの問題を回避するには、 execute()を呼び出す前に、SQLステートメント、パラメーターバインディング、およびデータ型を慎重に確認することをお勧めします。
pdostatement :: execute()を呼び出す前に、プリプロセシングステートメントの作業原則、パラメーターバインディングの方法、エラー処理、およびパラメータータイプの使用を理解することが非常に重要です。この知識を習得すると、コードのセキュリティとパフォーマンスを改善するだけでなく、一般的なエラーの発生を減らし、コードの保守性を高めることもできます。これらのエラーを回避することにより、開発者はより効率的で堅牢なデータベース操作コードを書き込むことができます。