准备好的语句如何实际工作? (PHP)

我正在寻找使用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没有这种奢侈,所以我正在自己做一些事情来模拟它。 究竟是在这里发生了什么?

谢谢!

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

基本工作stream程

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

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执行

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

 $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重复执行

准备好的语句可以重复执行。 在每次执行时,绑定variables的当前值被评估并发送到服务器。 该语句不再被parsing。 语句模板不会再次传输到服务器。

 /* 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(); 

准备好的陈述从根本上分离了数据命令 。 当两者之间的界限被错误的input所模糊时,就会发生SQL注入。 分离它们使注射成为不可能。

要做到这一点,你需要一个数据库服务器和该数据库的客户端与此function。 正如你所发现的那样,许多数据库客户端实际上并没有使用准备好的语句function,而只是转义数据以便在查询中用来模拟预准备语句。 这仍然可以被认为是安全的…这些客户一般都经过严格testing。

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