The use of SQL prepared statements and anti-injection

Many mature databases support the concept of Prepared Statements. What are they?

You can think of them as a compiled template of SQL statements to be executed that can be customized with different variable parameters.

Prepared statements have two main advantages:

  • A query only needs to be parsed (or prepared) once, but can be executed multiple times with the same or different parameters.
    • When a query is prepared (Prepared), the database analyzes, compiles, and optimizes its plan to execute the query.
    • For complex queries, if you have to repeat the query with different parameters but the same structure many times, this process will take a lot of time and make your application slower.
    • By using a prepared statement you can avoid repeated analysis, compilation, and optimization.
    • Simply put, prepared statements use fewer resources and execute faster.
  • Arguments passed to prepared statements do not need to be quoted, the underlying driver handles this for you.
    • If your application uses prepared statements exclusively, you can be sure that no SQL injection will occur.
    • However, this is still risky if you are still building other parts of the query based on untrusted input

Precisely because prepared statements are so useful, it is the only mock implementation provided by PDO for databases that do not support this feature.

This allows you to use a uniform data access specification without having to worry about whether the database itself has this feature.

/*
使用预处理语句重复插入数据(1)
此示例演示了一个通过向命名占位符代入一个name和一个value值来执行的INSERT查询
*/
$stmt= $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value); //插入一行
$name= 'one';
$value= 1;
$stmt->execute();//使用不同的值插入另一行
$name= 'two';
$value= 2;
$stmt->execute();

/*
使用预处理语句重复插入数据(2)
此示例演示了一个通过向用?表示的占位符代入一个name和一个value值来执行的INSERT查询
*/
$stmt= $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)");
$stmt->bindParam(1, $name);
$stmt->bindParam(2, $value); // 插入一行
$name= 'one';
$value= 1;
$stmt->execute(); // 使用不同的值插入另一行
$name= 'two';
$value= 2;
$stmt->execute();

/*
通过预处理语句获取数据
此示例演示使用从表单获取的数据为关键值来执行查询获取数据。用户的输入会被自动添加引号,所以这儿不存在SQL注入攻击的危险。
*/
$stmt= $dbh->prepare("SELECT * FROM REGISTRY where name = ?");
    if($stmt->execute(array($_GET['name']))) {
        while($row= $stmt->fetch()) {
        print_r($row);
    }
}

In fact, the mainstream PHP frameworks support Prepared Statements, and it is much simpler. The following are examples of ThinkPHP model support:

// 实例化User模型
$model= D('User');

// 定义预处理传入数据
$data['username'] = 'deeka';
$data['password'] = '123456';

// 数据预处理
if($model->create($data)){
    $model->add();
}

References

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325520987&siteId=291194637