在 PHP 中执行参数化查询的最佳实践? [复制]

Posted

技术标签:

【中文标题】在 PHP 中执行参数化查询的最佳实践? [复制]【英文标题】:Best practice for executing parameterised queries in PHP? [duplicate] 【发布时间】:2013-07-28 17:32:26 【问题描述】:

好的,现在我的网站上有 100-200 个查询,全部参数化。

这是其中之一的示例:

$mysqli = new mysqli('localhost', 'user', 'password', 'db_name');
if ($mysqli->connect_errno) 
    printf("Connect failed: %s\n", $mysqli->connect_error);
    exit();


$stmt = $mysqli->prepare("SELECT `x` FROM `y` WHERE `z` = ?");
$stmt->bind_param("s", $test);
$stmt->execute();
$stmt->store_result();
$stmt->close();

$mysqli->close();

所以我的问题是,打开/关闭与数据库的连接的最佳做法是什么?

最好保持连接打开,运行多个查询,然后在页面末尾关闭连接。像这样:

$mysqli = new mysqli('localhost', 'user', 'password', 'db_name');
if ($mysqli->connect_errno) 
    printf("Connect failed: %s\n", $mysqli->connect_error);
    exit();


$stmt = $mysqli->prepare("SELECT `a` FROM `b` WHERE `c` = ?");
$stmt->bind_param("s", $test1);
$stmt->execute();
$stmt->store_result();
$stmt->close();

$stmt = $mysqli->prepare("SELECT `x` FROM `y` WHERE `z` = ?");
$stmt->bind_param("s", $test2);
$stmt->execute();
$stmt->store_result();
$stmt->close();

$mysqli->close();

或者最好在每次查询之前打开连接,然后立即关闭?像这样:

$mysqli = new mysqli('localhost', 'user', 'password', 'db_name');
if ($mysqli->connect_errno) 
    printf("Connect failed: %s\n", $mysqli->connect_error);
    exit();


$stmt = $mysqli->prepare("SELECT `a` FROM `b` WHERE `c` = ?");
$stmt->bind_param("s", $test1);
$stmt->execute();
$stmt->store_result();
$stmt->close();

$mysqli->close();


$mysqli = new mysqli('localhost', 'user', 'password', 'db_name');
if ($mysqli->connect_errno) 
    printf("Connect failed: %s\n", $mysqli->connect_error);
    exit();


$stmt = $mysqli->prepare("SELECT `x` FROM `y` WHERE `z` = ?");
$stmt->bind_param("s", $test2);
$stmt->execute();
$stmt->store_result();
$stmt->close();

$mysqli->close();

目前我在页面打开 <html> 标记之前打开连接,然后在关闭 </html> 标记之后关闭它。这是安全/良好的做法吗?

【问题讨论】:

顺便说一句,所有这些东西都与参数化查询无关,而是与一般查询有关 @YourCommonSense 我意识到,但是上次我在这个网站上发布了一个问题 - 事实上,你自己因为不使用参数化查询而攻击我。以这种方式发布我的问题是为了确保问题是富有成效的,并且不会因进入参数化查询的优缺点而偏离任何 cmet。 【参考方案1】:

打开和关闭连接会占用资源,因此目标是尽可能少地打开/关闭连接,从而在打开单个连接时执行尽可能多的查询。

这是否意味着在脚本启动时打开连接并在完成时关闭它,或者为每个查询打开/关闭,这取决于您的应用程序的性质。

例如,如果您的大多数脚本都有一个或多个查询,那么打开/关闭连接以及脚本的开头和结尾将是最好的。另一方面,如果您的大多数脚本都是无查询的,那么在您想要执行查询时建立连接将是您最好的选择。

【讨论】:

【参考方案2】:

最好保持连接打开,运行多个查询,然后在页面末尾关闭连接。

是的。

或者最好在每次查询之前打开连接,然后立即关闭?

没有。

目前我在页面开始标记之前打开连接,然后在关闭之后关闭它。这是安全/良好的做法吗?

没有。 您的应用程序必须以这样一种方式构建,以便在页面打开 <head> 标记之前轻松关闭连接,因为所有必须在任何输出开始之前完成数据库交互。

php 中执行参数化查询的最佳实践?

当然是创建一个函数,在一行而不是十行中执行(并处理所有这些打开/关闭的东西),就像这样

$data = $db->get("SELECT `a` FROM `b` WHERE `c` = ?", $test1);

【讨论】:

为什么必须在<head>之前关闭连接? 不一定要关闭,但每次数据库交互显然都必须在页面打开 标签之前完成。 我从来不知道有这样的要求——你能引用它的来源吗? 哦,刚刚读了一些关于业务逻辑与显示逻辑分离的内容。我手头没有链接,因为我发现这个原理本身就很合乎逻辑,但我相信它也很容易用谷歌搜索。简而言之,在所有数据准备好之前不应该开始输出。 我知道将这些东西分开是一种很好的做法,但是说连接“必须在 [...] <head> 之前关闭”是错误的,而实际上它们并没有。也许“必须”应该改为“应该”。

以上是关于在 PHP 中执行参数化查询的最佳实践? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

在带有 PDO 的 PHP 中,如何检查最终的 SQL 参数化查询? [复制]

在带有 PDO 的 PHP 中,如何检查最终的 SQL 参数化查询? [复制]

API设计与开发之最佳实践

复制通过引用方法传递的参数的最佳实践,避免无意中修改参数

哪种子集化方法是最佳实践? [复制]

如何正确使用 PDO 对象进行参数化 SELECT 查询