准备好的陈述如何实际运作? (PHP)

时间:2013-11-17 05:00:39

标签: php node.js

我正在考虑将node.js / socket.io用于实时用户到用户界面。我习惯使用PHP,它有很棒的,非常简单的预备语句系统。例如:

$dbh->prepare('SELECT * FROM table WHERE val=:val1 OR val=:val2');
$dbh->execute(array('val1'=>'stuff','val2'=>'more stuff'));

现在,node.js没有这种奢侈品,所以我正在寻找自己做一些事情来模拟它。到底究竟发生了什么?

谢谢!

2 个答案:

答案 0 :(得分:1)

预准备语句或参数化语句用于以高效率重复执行相同的语句。

基本工作流程

准备好的语句执行包括两个阶段:准备和执行。在准备阶段,将语句模板发送到数据库服务器。服务器执行语法检查并初始化服务器内部资源以供以后使用。

MySQL服务器支持使用带有?的匿名位置占位符。

1第一阶段:准备

$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}

/* Prepared statement, stage 1: prepare */
if (!($stmt = $mysqli->prepare("INSERT INTO test(id) VALUES (?)"))) {
    echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

2执行

准备之后是执行。在执行期间,客户端绑定参数值并将它们发送到服务器。服务器根据语句模板和绑定值创建语句,以使用先前创建的内部资源执行它。

$id = 1;
if (!$stmt->bind_param("i", $id)) {
    echo "Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error;
}

if (!$stmt->execute()) {
    echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}

3重复执行

准备好的陈述可以重复执行。每次执行时,都会评估绑定变量的当前值并将其发送到服务器。该语句不会再次解析。语句模板不会再次传输到服务器。

/* Prepared statement: repeated execution, only data transferred from client to server */
for ($id = 2; $id < 5; $id++) {
    if (!$stmt->execute()) {
        echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
    }
}

/* explicit close recommended */
$stmt->close();

答案 1 :(得分:0)

准备好的陈述从根本上将数据命令分开。当两个行之间的线路因输入错误而变得模糊时,就会发生SQL注入。将它们分开使得注射成为不可能。

要正确执行此操作,您需要具有此功能的该数据库的数据库服务器和客户端。正如您所发现的,许多数据库客户端实际上并不使用预准备语句功能,而只是转义数据以在查询中使用以模拟预准备语句。这仍然可以被认为是安全的......这些客户通常都经过严格的测试。

请注意,当客户端只是模拟它们时,您无法获得预准备语句的性能优势。

相关问题