PHP完全独学マニュアルlogin
PHP完全独学マニュアル
著者:php.cn  更新時間:2022-04-15 13:53:54

PHP MySQL 準備済みステートメント



プリペアドステートメントは、MySQL インジェクションを防ぐのに非常に役立ちます。


プリペアドステートメントとバインドされたパラメーター

プリペアドステートメントは、複数の同一の SQL ステートメントをより高い実行効率で実行するために使用されます。

お勧めのビデオチュートリアル: "mysqlチュートリアル"http://www.php.cn/course/list/51.html

準備されたステートメントの動作原理は次のとおりです:

  1. 前処理: SQL ステートメントのテンプレートを作成し、データベースに送信します。予約された値にはパラメータ「?」が付けられます。例:

INSERT
INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)
  1. SQL ステートメント テンプレートでのデータベースの解析、コンパイル、クエリの最適化、および出力せずに結果を保存します。 。

  2. 実行: 最後に、アプリケーションにバインドされた値がパラメータ (「?」マーク) に渡され、データベースがステートメントを実行します。パラメータ値が異なる場合、アプリケーションはステートメントを複数回実行できます。

SQL ステートメントを直接実行する場合と比較して、プリペアド ステートメントには 2 つの主な利点があります:

  • プリプロセスされたステートメントは分析時間を大幅に短縮し、(ステートメントは複数回実行されますが) クエリを 1 つだけ作成します。

  • パラメータをバインドすると、サーバーの帯域幅が削減されます。ステートメント全体ではなく、クエリのパラメータのみを送信する必要があります。

  • 前処理されたステートメントは、パラメーター値が送信された後に異なるプロトコルが使用され、データの正当性が保証されるため、SQL インジェクションに非常に役立ちます。


MySQLi 準備済みステートメント

次の例では、MySQLi で準備済みステートメントを使用し、対応するパラメーターをバインドします:

例 (MySQLi は準備済みステートメントを使用します)

<?php
$servername = "localhost";
$username = "username";
$password = 
"password";
$dbname = 
"myDB";
// 创建连接
$conn = new mysqli($servername, 
$username, $password, $dbname);
// 检测连接
if ($conn->connect_error) 
{
    die("连接失败: " . $conn->connect_error);
}
// 预处理及绑定
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) 
VALUES(?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname, 
$email);
// 设置参数并执行
$firstname = "John";
$lastname 
= "Doe";
$email = "john@example.com";
$stmt->execute();
$firstname 
= "Mary";
$lastname = "Moe";
$email = "mary@example.com";
$stmt->execute();
$firstname = "Julie";
$lastname = "Dooley";
$email = "julie@example.com";
$stmt->execute();
echo "新记录插入成功";
$stmt->close();
$conn->close();
?>
は、次の例の各行を解析します コード:
"INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)"
SQL ステートメントでは疑問符 (?) を使用します。ここでは、疑問符を整数、文字列、倍精度浮動小数点、およびブール値に置き換えることができます。

次に、bind_param() 関数を見てみましょう:

$stmt->bind_param("sss", $firstname, $lastname, $email);
この関数は SQL パラメーターをバインドし、データベースにパラメーターの値を伝えます。 「sss」パラメータ列は、残りのパラメータのデータ型を処理します。 s 文字は、パラメータが文字列であることをデータベースに伝えます。

パラメータには以下の4種類があります:

  • i - integer(整数型)

  • d - double(倍精度浮動小数点型)

  • s - string (文字列)

  • b - BLOB (バイナリ ラージ オブジェクト:バイナリ ラージ オブジェクト)

各パラメータは型を指定する必要があります。

データベースにパラメータのデータ型を伝えることで、SQL インジェクションのリスクを軽減できます。

Note 注: 他のデータ (ユーザー入力) を挿入する場合は、データの検証が非常に重要です。


PDO のプリペアドステートメント

次の例では、プリペアドステートメントを使用し、PDO でパラメータをバインドします。

例 (PDO はプリペアドステートメントを使用します)

<?php
$servername = "localhost";
$username = "username";
$password = 
"password";
$dbname = 
"myDBPDO";
try {
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", 
$username, $password);
    
// 设置 PDO 错误模式为异常
    $conn->setAttribute(PDO::ATTR_ERRMODE, 
PDO::ERRMODE_EXCEPTION);
    // 预处理 SQL 并绑定参数
    
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email)
    VALUES (:firstname, :lastname, :email)");
    
$stmt->bindParam(':firstname', $firstname);
    $stmt->bindParam(':lastname', 
$lastname);
    $stmt->bindParam(':email', $email);
    // 插入行
    $firstname = 
"John";
    $lastname = "Doe";
    
$email = "john@example.com";
    $stmt->execute();
    
// 插入其他行
    $firstname = "Mary";
    
$lastname = "Moe";
    $email = "mary@example.com";
    
$stmt->execute();
    // 插入其他行
    
$firstname = "Julie";
    $lastname = "Dooley";
    
$email = "julie@example.com";
    $stmt->execute();
    
echo "新记录插入成功";
}
catch(PDOException $e)
 {
    
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
?>

PHP中国語ウェブサイト