最新的Web開發教程
 

PHP預處理語句


預處理語句是對SQL注入是非常有用的。


預處理語句和綁定參數

預準備語句是用於執行該方法的特徵(or similar)以高效率反复SQL語句。

準備好的語句的基本工作原理是這樣的:

  1. 準備:一個SQL語句的模板創建和發送到數據庫。 某些值未指定,所謂的參數(labeled "?") 例如:INSERT INTO MyGuests VALUES(?, ?, ?)
  2. 該數據庫將分析,編譯和執行的SQL語句模板查詢優化,並將結果但不執行
  3. 執行:在以後的時間,將應用程序綁定值參數,數據庫執行該語句。 因為它與不同價值觀想要應用程序可以執行該語句多次

相比於直接執行SQL語句,預處理語句具有兩個主要優點:

  • 準備的語句作為減少對查詢的準備做一次解析時間(although the statement is executed multiple times)
  • 綁定參數減少帶寬的服務器,因為你需要每次只傳送參數,而不是整個查詢
  • 準備的語句是針對SQL注入是非常有用的,因為參數值,這些值在以後使用不同的協議來發送,不需要被正確轉義。 如果原始報表模板不是從外部輸入導出,不會出現SQL注入。

在庫MySQLi預處理語句

下面的示例使用準備的語句和在庫MySQLi綁定參數:

實施例(MySQLi with Prepared Statements)

<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";

// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// prepare and bind
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname, $email);

// set parameters and execute
$firstname = "John";
$lastname = "Doe";
$email = "[email protected]";
$stmt->execute();

$firstname = "Mary";
$lastname = "Moe";
$email = "[email protected]";
$stmt->execute();

$firstname = "Julie";
$lastname = "Dooley";
$email = "[email protected]";
$stmt->execute();

echo "New records created successfully";

$stmt->close();
$conn->close();
?>

代碼行以從上面的例子解釋:

"INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)"

在我們的SQL,我們插入一個問號(?)我們希望在一個整數,字符串,雙或BLOB值來代替。

然後,看看在bind_param()函數:

$stmt->bind_param("sss", $firstname, $lastname, $email);

該功能結合了參數的SQL查詢,並告訴數據庫什麼的參數。 在"sss"的說法列出的數據類型的參數。 的性格告訴MySQL的參數是一個字符串。

參數可以為四種類型之一:

  • 我 - 整數
  • ð - 雙
  • 秒 - 字符串
  • b - BLOB

我們必須對這些每個參數之一。

通過告訴MySQL的期待什麼類型的數據,我們盡量減少SQL注入的風險。

注意:如果我們要插入外部源的任何數據(like user input) ,這是非常重要的數據被消毒和驗證。


在PDO預處理語句

下面的示例使用準備的語句和在PDO綁定參數:

實施例(PDO with Prepared Statements)

<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDBPDO";

try {
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    // set the PDO error mode to exception
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // prepare sql and bind parameters
    $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);

    // insert a row
    $firstname = "John";
    $lastname = "Doe";
    $email = "[email protected]";
    $stmt->execute();

    // insert another row
    $firstname = "Mary";
    $lastname = "Moe";
    $email = "[email protected]";
    $stmt->execute();

    // insert another row
    $firstname = "Julie";
    $lastname = "Dooley";
    $email = "[email protected]";
    $stmt->execute();

    echo "New records created successfully";
    }
catch(PDOException $e)
    {
    echo "Error: " . $e->getMessage();
    }
$conn = null;
?>