如何在Postgres中使用预处理语句

14
我知道我需要准备好的语句,因为在一个脚本中我会对数据库进行多次调用。
我想得到以下句子的具体例子
“查看类型转换、验证和清理变量以及使用带有预处理语句的PDO。”
我知道他所说的验证和清理变量的含义。然而,我并不完全确定预处理语句。我们如何准备语句?通过过滤,也就是通过清理吗?还是通过一些PDO层?层的定义是什么?
在该语句中,“预处理语句”是什么意思?请使用具体示例。
4个回答

8
在语句中,“prepared statements”是什么意思?
根据文档
这个功能允许重复使用的命令只被解析和计划一次,而不是每次执行时都要进行。
请参见pg_prepare 以下是上述页面中的示例:
<?php
// Connect to a database named "mary"
$dbconn = pg_connect("dbname=mary");

// Prepare a query for execution
$result = pg_prepare($dbconn, "my_query", 'SELECT * FROM shops WHERE name = $1');

// Execute the prepared query.  Note that it is not necessary to escape
// the string "Joe's Widgets" in any way
$result = pg_execute($dbconn, "my_query", array("Joe's Widgets"));

// Execute the same prepared query, this time with a different parameter
$result = pg_execute($dbconn, "my_query", array("Clothes Clothes Clothes"));
?>

MySQL预处理文档很好地回答了以下问题:

  • 为什么要使用预处理语句?
  • 何时应该使用预处理语句?

你的示例代码和Robot的功能一样吗?对我来说,它们比Robot的清晰得多。他似乎使用了很多数组,这让我很难阅读。 - Léo Léopold Hertz 준영
1
@Masi - 我提供的示例来自pg_prepare文档页面。它们更容易理解,但我认为@Glass Robot的示例更贴近实际(例如,命名标记)。我建议您尽快动手实践。没有“一刀切”的示例。 - karim79
1
你的回答没有使用PDO。这让我认为你可以在没有PDO的情况下使用预处理语句。PDO似乎只提供数据库独立性。 - Léo Léopold Hertz 준영
似乎 pg_query = pg_prepare + pg_execution - 能够将列表变量运行到语句中的能力 - Léo Léopold Hertz 준영
请查看我的回复,在此链接中或位于https://dev59.com/pHM_5IYBdhLWcg3wvV5w#1247767。 - Léo Léopold Hertz 준영

6
这意味着它可以通过消除手动引用参数的需求来帮助您防止SQL注入攻击。您可以使用命名或问号标记来代替将变量放入SQL语句中,当执行语句时,实际值将被替换。
PHP手册中对PDO的定义为:“PHP数据对象(PDO)扩展定义了一个轻量级、一致的接口,用于在PHP中访问数据库。”
请参见PHP手册上有关PDOPDO::prepare的内容。
以下是一个使用命名标记的预处理语句示例:
<?php
$pdo = new PDO('pgsql:dbname=example;user=me;password=pass;host=localhost;port=5432');

$sql = "SELECT username, password
FROM users
WHERE username = :username
AND password = :pass";

$sth = $pdo->prepare($sql);
$sth->execute(array(':username' => $_POST['username'], ':pass' => $_POST['password']));
$result = $sth->fetchAll();

使用问号标记的预处理语句示例:

<?php
$pdo = new PDO('pgsql:dbname=example;user=me;password=pass;host=localhost;port=5432');

$sql = "SELECT username, password
FROM users
WHERE username = ?
AND password = ?";

$sth = $pdo->prepare($sql);
$sth->execute(array($_POST['username'], $_POST['password']));
$result = $sth->fetchAll();

您的命令似乎从用户表中选择用户名和密码列,例如当username=a且password=a时。这使我觉得该代码在现实生活中不太实用,因为在已知列名的情况下选择这两个列名是没有意义的。但是,如果根据这两个选择第三列,那么您的方法似乎可以奏效。似乎用户的输入经过处理,以使得在执行带有用户输入的查询时出现故障/意外也不会更改原始数据,因此没有SQL注入,例如,如果在准备过程中失败,则停止... - Léo Léopold Hertz 준영

0

如何准备语句:

您只需定义一次查询,就可以使用不同的值多次调用它(例如,在循环中)。

$result = pg_prepare($dbconn, "my_query", 'SELECT * FROM shops WHERE name = $1');
$result = pg_execute($dbconn, "my_query", array("Joe's Widgets"));
$result = pg_execute($dbconn, "my_query", array("row two"));
$result = pg_execute($dbconn, "my_query", array("row three"));

请参见:http://us2.php.net/manual/zh/function.pg-execute.php


如果你只处理字符串,这可能会有所帮助,但我讨厌 https://www.php.net/manual/en/function.pg-prepare.php 没有 int 数据类型的示例,所以我写了一个:$result = pg_prepare($cn, "query1", 'SELECT url FROM table.link WHERE id = $1'); $result = pg_execute($cn, "query1", array(4044)); echo pg_fetch_array($result)[0]; - Rublacava

0
回复Karim79的答案
这个
$result = pg_prepare($dbconn, "query1", 'SELECT passhash_md5 FROM users WHERE email = $1');

看起来和这个一样

$result = pg_prepare($dbconn, "query1", 'SELECT passhash_md5 FROM users WHERE email = ?');

结论:使用pg_preparepg_execute可以使PHP更加高效,因为您不需要考虑净化。它还有助于您使用PDO。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接