参数化查询未知总参数

时间:2014-04-23 23:13:59

标签: php mysql sql-parametrized-query

我正在使用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." ");

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

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

$q .= " AND `age` = ".$dbs->escapeInt($_POST['age')]." ";

答案 1 :(得分:0)

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

是的,让我们开始并且不会忽视它 - 如果查询文本包含[用户提供的]数据那么代码在safemysql's(以及安全的SQL使用)租户之一的违反中,以下必然是真的!

  

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

然后解决方案是使用占位符数据数组动态构建查询文本 - 但单独。在任何时候都不会将DQL(SQL语法)和数据混合在一起。正是这种分离(以及较低级别的保证)确保在遵循此方法时没有SQL Injection

$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,我们几乎就在那里!现在,创建将传递的数组invoke the method supplying an array for the parameters

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

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

并且,完成了!