最新的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;
?>