过滤查询的php参数化查询

Posted

技术标签:

【中文标题】过滤查询的php参数化查询【英文标题】:php parameterized query on filtered query 【发布时间】:2014-04-06 14:44:09 【问题描述】:

我正在根据用户应用的过滤器构建查询。一切都按照我想要的方式进行,拉取数据。我现在已经到了安全点。当我的“WHERE”可以添加多个过滤器时,我怎样才能确保它的安全。

$sql_Year = $_GET['year'];
$sql_Model = $_GET['model'];
$sql_Style = $_GET['style'];
$sql_Color = $_GET['color'];

if ( !empty($sql_Year) ) $insertY .= " and Year='$sql_Year'";
if ( !empty($sql_Model) ) $insertY .= " and Model='$sql_Model'";
if ( !empty($sql_Style) ) $insertY .= " and Body='$sql_Style'";
if ( !empty($sql_Color) ) $insertY .= " and Colour='$sql_Color'";

$stmt = $con->prepare("SELECT DISTINCT(`Year`) FROM `cars` WHERE `New/Used` =  'N' ".$insertY." ORDER BY `Year` ASC ");
$stmt->execute();
$stmt->bind_result($Year);


while ($row = $stmt->fetch()) 

    

我听从了您的建议并制作了数组。我现在收到一个错误:mysqli_stmt::bind_param() [mysqli-stmt.bind-param]:类型定义字符串中的元素数与绑定变量数不匹配。我的新代码是:

$get_Year = $_GET['year'];
$get_Model = $_GET['model'];
$get_Style = $_GET['style'];
$get_Color = $_GET['color'];

$YearArray = array();
$YearValues .= "WHERE `New/Used`=?";
$YearTypes .= "s";
array_push($YearArray, "U");
if ($get_Year != "") 
    $YearValues .= " and `Year`=?";
    $YearTypes .= "s";
    array_push($YearArray, "2004");

if ($get_Model != "") 
    $YearValues .= " and Model=?";
    $YearTypes .= "s";
    array_push($YearArray, $get_Model);

if ($get_Style != "") 
    $YearValues .= " and Body=?";
    $YearTypes .= "s";
    array_push($YearArray, $get_Style);

if ($get_Color != "") 
    $YearValues .= " and Colour=?";
    $YearTypes .= "s";
    array_push($YearArray, $get_Color);

$YearVariables = implode(',', $YearArray);

$stmt = $con->prepare("SELECT DISTINCT(`Year`) FROM `cars` ".$YearValues." ORDER BY `Year` ASC ");
$stmt->bind_param($YearTypes, $YearVariables); 
$stmt->execute();
$stmt->bind_result($Year);

我可以将这样的数组用于 bind_param 吗?

【问题讨论】:

您需要构建两个并行数组:一个用于您正在使用的“值”,一个用于“占位符”。最后,你将它们全部拼凑在一起,最终得到一个动态的准备好的语句,这在术语上有点矛盾。 我根据您的建议做了一些更新。请使用新代码查看我的编辑。谢谢!寻求进一步的帮助。 ***.com/questions/11231597/… 【参考方案1】:

您需要清理输入!这是我通常使用的卫生功能:

function sanitize($string)
    $string = str_replace(array('"',"'"), array(""","'"),$string);
    $string = trim($string);
    $string = stripslashes($string);
    $string = mysql_real_escape_string($string);
    return $string;

这样使用:

if ( !empty($sql_Year) ) $insertY .= " and Year='".sanitize($sql_Year)."'";
if ( !empty($sql_Model) ) $insertY .= " and Model='".sanitize($sql_Model)."'";
if ( !empty($sql_Style) ) $insertY .= " and Body='".sanitize($sql_Style)."'";
if ( !empty($sql_Color) ) $insertY .= " and Colour='".sanitize($sql_Color)."'";

【讨论】:

只使用mysql_real_escape_string有什么问题? -1 因为没有意识到 OP 没有使用已弃用的 mysql_* 函数。

以上是关于过滤查询的php参数化查询的主要内容,如果未能解决你的问题,请参考以下文章

Google Bigquery - 运行参数化查询 - php

什么是参数化查询?

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

执行参数化 N1QL 查询时,Couchbase 不使用带过滤器的索引

PHP MySQL 查询参数化问题

动态 SQL,参数化查询