ホームページ  >  記事  >  バックエンド開発  >  PHP -- PDO プリペアド ステートメントとストアド プロシージャ

PHP -- PDO プリペアド ステートメントとストアド プロシージャ

伊谢尔伦
伊谢尔伦オリジナル
2016-11-22 09:34:12983ブラウズ

さらに多くの成熟したデータベースが、準備されたステートメントの概念をサポートしています。準備されたステートメントとは何ですか?これは、実行する SQL のコンパイルされたテンプレートと考えてください。変数パラメーターを使用してカスタマイズできます。プリペアドステートメントには 2 つの大きな利点があります:

クエリは 1 回解析 (または前処理) するだけで済みますが、同じまたは異なるパラメーターを使用して複数回実行できます。クエリの準備が完了すると、データベースはクエリを実行するための計画を分析、コンパイル、最適化します。複雑なクエリの場合、このプロセスには時間がかかり、同じクエリを異なるパラメータで複数回繰り返す必要がある場合、アプリケーションの速度が大幅に低下する可能性があります。準備されたステートメントを使用すると、分析/コンパイル/最適化サイクルの繰り返しを回避できます。簡単に言えば、準備されたステートメントは使用するリソースが少ないため、より高速に実行されます。

準備されたステートメントに指定されたパラメーターを引用符で囲む必要はありません。ドライバーが自動的に処理します。アプリケーションでプリペアド ステートメントのみを使用する場合、SQL インジェクションは確実に発生しません。 (ただし、クエリの他の部分がエスケープされていない入力から構築されている場合は、依然として SQL インジェクションのリスクが存在します)。

準備されたステートメントは非常に便利ですが、その唯一の機能は、ドライバーがサポートしていない場合に PDO が処理をシミュレートすることです。これにより、データベースにそのような機能があるかどうかに関係なく、アプリケーションは同じデータ アクセス パターンを使用できるようになります。

例 #1 繰り返し挿入に準備済みステートメントを使用する

次の例では、対応する名前付きプレースホルダーを名前と値で置き換えることによって挿入クエリを実行します

<?php
    $stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
    $stmt->bindParam(&#39;:name&#39;, $name);
    $stmt->bindParam(&#39;:value&#39;, $value);
    // 插入一行
    $name = &#39;one&#39;;
    $value = 1;
    $stmt->execute();
    // 用不同的值插入另一行
    $name = &#39;two&#39;;
    $value = 2;
    $stmt->execute();
?>

例 #2 繰り返し挿入に準備済みステートメントを使用する

以下の例 挿入クエリを実行する? プレースホルダーを名前と値に置き換えます。

<?php
    $stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)");
    $stmt->bindParam(1, $name);
    $stmt->bindParam(2, $value);
    // 插入一行
    $name = &#39;one&#39;;
    $value = 1;
    $stmt->execute();
    // 用不同的值插入另一行
    $name = &#39;two&#39;;
    $value = 2;
    $stmt->execute();
?>

例 #3 準備されたステートメントを使用してデータを取得する

次の例では、指定された形式のキー値に基づいてデータを取得します。ユーザー入力は自動的に引用されるため、SQL インジェクション攻撃の危険はありません。

<?php
    $stmt = $dbh->prepare("SELECT * FROM REGISTRY where name = ?");
    if ($stmt->execute(array($_GET[&#39;name&#39;]))) {
        while ($row = $stmt->fetch()) {
            print_r($row);
        }
    }
?>

データベース ドライバーがサポートしている場合、アプリケーションは出力パラメーターと入力パラメーターをバインドすることもできます。出力パラメーターは通常、ストアド プロシージャから値を取得するために使用されます。出力パラメータをバインドするときに、指定されたパラメータの長さを知っておく必要があるため、出力パラメータの使用は入力パラメータよりも少し複雑です。パラメータにバインドされた値が推奨される長さを超える場合、エラーが生成されます。

例 #4 出力パラメーターを使用したスト​​アド プロシージャの呼び出し

<?php
    $stmt = $dbh->prepare("CALL sp_returns_string(?)");
    $stmt->bindParam(1, $return_value, PDO::PARAM_STR, 4000);
    // 调用存储过程
    $stmt->execute();
    print "procedure returned $return_value\n";
?>

入力値と出力値の両方を使用してパラメーターを指定することもでき、構文は出力パラメーターと似ています。次の例では、文字列「hello」がストアド プロシージャに渡され、ストアド プロシージャが返されるときに、hello がストアド プロシージャによって返された値に置き換えられます。

例 #5 入出力パラメーターを使用したスト​​アド プロシージャの呼び出し

<?php
    $stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)");
    $value = &#39;hello&#39;;
    $stmt->bindParam(1, $value, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000);
    // 调用存储过程
    $stmt->execute();
    print "procedure returned $value\n";
?>

例 #6 プレースホルダーの無効な使用

<?php
    $stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE &#39;%?%&#39;");
    $stmt->execute(array($_GET[&#39;name&#39;]));
    // 占位符必须被用在整个值的位置
    $stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE ?");
    $stmt->execute(array("%$_GET[name]%"));
?>


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。