2

我正在使用 safemysql 类进行参数化查询https://github.com/colshrapnel/safemysql。通常,在准备查询时,它是这样的:

$entries = $db->getAll("SELECT * FROM table WHERE age = ?i AND name = ?s ",$age,$name);

这种我事先知道要解析的参数总数的查询是非常直接的,但似乎我堆积在我不知道我将使用多少参数的查询中 - 例如。搜索表格:

我想做的是参数化以下查询:

if($_POST['nameparts']){

    $parts = explode(' ',$_POST['nameparts']);

    foreach((array)$parts as $part){

        $q .= " AND ( `name` LIKE '%".$part."%' OR `firstname` LIKE '%".$part."%' ) ";

    }

    if($_POST['age'])
        $q .= " AND `age` = '".$_POST['age']."' ";

    $entries = $dbs->getAll("SELECT * FROM table WHERE 1 = 1 ".$q." ");

有什么建议么?

4

2 回答 2

1

看起来 safemysql 不支持可变数量的占位符(否则您可以与查询并行构建参数数组)。但是您可以使用escapeString(...). 它会给你同样的安全水平,但不是那么优雅。例如:

$q .= " AND `age` = ".$dbs->escapeInt($_POST['age')]." ";
于 2014-04-23T23:32:39.977 回答
0

与使用用户提供的数据的任何其他 SQL 查询一样,要以真正安全的方式处理此问题(或者更确切地说是推迟它所属的工作),请使用 placeholders

是的,让我们这个目标开始,不要忽视它- 如果查询文本包含 [用户提供的] 数据,那么代码违反safemysql 的(和安全 SQL 使用)租户之一,以下不一定是真的!

[safemysql] 是安全的,因为每个动态查询部分 [或“用户数据位”] 通过占位符进入查询。

解决方案是使用占位符和数据数组动态构建查询文本,但要分开构建。DQL(SQL 语法)和数据绝不会混在一起。正是这种分离(以及较低级别的保证)保证了在遵循这种方法时不会发生SQL 注入。

$data = array();
$q = "SELECT * FROM table WHERE 1 = 1 ";
if($_POST['nameparts']){
    $parts = explode(' ',$_POST['nameparts']);
    foreach((array)$parts as $part){            
        $q .= " AND (`name` LIKE ?s OR `firstname` LIKE ?s )";
        $data[] = '%' . $part . '%'; // add one for each replacement
        $data[] = '%' . $part . '%';
    }
    if($_POST['age']) {
        $q .= " AND `age` = ?i ";
        $data[] = $_POST['age'];
    }
}

现在我们有了带有占位符的查询文本和要绑定的数据数组。Yippee,我们快到!现在,创建将被传递的数组并调用为参数提供数组的方法

$params = array($q);
$params = array_merge($params, $data);

$entries = call_user_func_array(array($dbs, 'getAll'), $params);

而且,完成了!

于 2014-04-23T23:51:30.750 回答