Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/229.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 当它';绑定变量很难使用吗?_Php_Mysql_Sql_Sql Injection - Fatal编程技术网

Php 当它';绑定变量很难使用吗?

Php 当它';绑定变量很难使用吗?,php,mysql,sql,sql-injection,Php,Mysql,Sql,Sql Injection,我习惯于使用参数化语句,但在此语句中,参数的数量可能会根据搜索字符串中的字数而变化。 所以“食物”=1参数,“一些食物”=2,“很多食物”=3等 我已经基本上建立了一个查询,允许搜索一个网站,为了提高功能,我已经使它有可能搜索没有它必须是一个完美的匹配栏的某些单词 例如,我知道一个俱乐部的名称及其所在城市 名称:薄荷俱乐部, 城市:利兹 上校:利兹薄荷俱乐部 搜索:“Mint Leeds”通常会导致找不到该行。但通过这种修改,它是有效的 对于未知数量的参数,我基本上想知道如何保护我的语句,因为我

我习惯于使用参数化语句,但在此语句中,参数的数量可能会根据搜索字符串中的字数而变化。
所以“食物”=1参数,“一些食物”=2,“很多食物”=3等

我已经基本上建立了一个查询,允许搜索一个网站,为了提高功能,我已经使它有可能搜索没有它必须是一个完美的匹配栏的某些单词

例如,我知道一个俱乐部的名称及其所在城市
名称:薄荷俱乐部,
城市:利兹 上校:利兹薄荷俱乐部

搜索:“Mint Leeds”通常会导致找不到该行。但通过这种修改,它是有效的

对于未知数量的参数,我基本上想知道如何保护我的语句,因为我认为它仍然可以接受sql注入

代码如下:

$keystring = $mysqli->real_escape_string($_POST["s"]);
$key = strtoupper($keystring);

$key_arr = explode(" ", $key);
$num_key = count($key_arr);

if($num_key >= 2){
    $where = '';
    foreach($key_arr as $val){
        $where .= "(CONCAT(name,' ',city) LIKE '%".$val."%') AND ";
    }
    $where = substr($where, 0, -4);
    $clubWhere = $where;
}
else{
    $key = "%".$key."%";
    $clubWhere = "(CONCAT(name,' ',city) LIKE '".$key."')";
}

$search_stmt = $mysqli->prepare("SELECT id, name, type AS 'col3', city AS 'col4', 'Club' AS 'table' FROM studentnights_clubs WHERE ".$clubWhere."
                                    UNION
                                    SELECT id, name, description AS 'col3', image AS 'col4', 'Event' AS 'table' FROM studentnights_events WHERE UCASE(name) LIKE ?
                                    UNION
                                    SELECT id, name, '' AS 'col3', '' AS 'col4', 'Genre' AS 'table' FROM studentnights_music WHERE UCASE(name) LIKE ?
                                    ORDER BY
                                        CASE
                                            WHEN name LIKE ? THEN 1
                                            WHEN name LIKE ? THEN 3
                                            ELSE 2
                                        END
                                    LIMIT 10");
$search_stmt->bind_param('ssss', $key, $key, $key, $key);
$search_stmt->execute();
$search_stmt->store_result();
$search_stmt_num = $search_stmt->num_rows;
$search_stmt->bind_result($id, $name, $col3, $col4, $table);

您的
$val
$key
项是用户提供的搜索参数,因此您需要确保它们中的垃圾无法进入查询

一种可能性是:准备两个不同的SQL语句,并使用具有适当数量的绑定变量的SQL语句

另一种方法是:在使用传入字符串构造SQL语句之前对其进行清理。你说它们是地名,应该像
'newcastle-on-tyne'
'denver'
,或者
'newyork'
。它们可能不是新的;删除超级用户表;'例如

下面是你如何对它们进行消毒

$val = $mysqli->real_escape_string(preg_replace('[^- A-Za-z0-9]', '', $val ));
这行代码将删除
$val
中除字母、数字、空格和破折号以外的所有字符。然后,它将把转义放入字符串中,以便为mysqli对其进行清理

如果预处理
”新建;删除超级用户表;'
您将获得
'newdroptablesuperusers'
,它可以安全地在查询中使用,尽管没有意义

您还可以在用户提供的搜索词中查找禁止使用的字符,如果存在,则拒绝进行搜索

听着,我们都知道使用绑定变量要安全得多,但是如果你不能,你仍然可以清理这些东西

  • 遗憾的是,您选择了原始mysqli来完成任务——这是有史以来最麻烦的API
  • 对于全文搜索,您应该真正使用专用的mysql功能或外部搜索引擎,如Sphinx搜索。它不仅可以让您摆脱这种繁重且不充分的代码,而且它实际上可以在真正的数据库中工作,而不仅仅是在一百行的测试记录集中
  • 如果您想坚持使用不充分的mysql搜索和MySQLIAPI(根据我的经验,PHP用户特别不愿意使用合适的工具),那么至少要使用参数,然后使用动态绑定 类似这样的东西(删除所有无用的分支)

    然后将其他值添加到$values数组中

    $values[] = $key;
    $values[] = $key;
    $values[] = $key;
    $values[] = $key;
    

    然后像这里解释的那样使用动态绑定

    非常不同场景的可能重复,我知道如何防止注入,只是在参数可能变化到未知数字的情况下不这样做。这可能有助于这个问题,就像我在这里做的一样,真的,没有参数化。谢谢你的帮助。我希望有办法改变“bind_param”语句,使其能够灵活地改变参数。将值放入数组,并使用
    str_repeat(?,count($arr)-1)。”
    来构建占位符。非常感谢您的回复,我将使用您的$val清除方法。但是,准备两个不同的语句不会起作用,因为绑定变量的数量永远不会知道,它们取决于执行搜索的用户。真的需要帮助。有我可以用来检查的禁止字符列表吗?
    $values[] = $key;
    $values[] = $key;
    $values[] = $key;
    $values[] = $key;