0

我正在使用 fatfree 框架,在前端我使用带有服务器端处理的 jQuery 数据表插件。因此,我的服务器端控制器可能会或可能不会收到可变数量的信息,例如要排序的可变数量的列,可变数量的过滤选项等等。因此,如果我没有收到任何排序请求,我不需要ORDER BY在我的查询中有一部分。所以我想根据特定的条件生成部分查询字符串,并在最后加入它以获得最终的执行查​​询。但是,如果我这样做,我将不会进行任何非常糟糕的数据清理。

有没有办法可以使用框架内部清理方法来部分构建查询字符串?还有比我的方法更好/更安全的方法吗?

4

1 回答 1

1

只需使用参数化查询。他们在这里是为了防止 SQL 注入。

允许使用两种可能的语法:

  1. 带问号占位符:

    $db->exec('SELECT * FROM mytable WHERE username=? AND category=?',
      array(1=>'John',2=>34));
    
  2. 带有命名占位符:

    $db->exec('SELECT * FROM mytable WHERE username=:name AND category=:cat',
      array(':name'=>'John',':cat'=>34));
    

编辑:

此处的参数用于过滤字段值,而不是列名,以便更具体地回答您的问题:

  • 您必须通过参数传递过滤值以避免 SQL 注入
  • 您可以通过对数组进行测试来检查列名是否有效

这是一个简单的例子:

$columns=array('category','age','weight');//columns available for filtering/sorting
$sql='SELECT * FROM mytable';
$params=array();

//filtering
$ctr=0;
if (isset($_GET['filter']) && is_array($_GET['filter'])
  foreach($_GET['filter'] as $col=>$val)
    if (in_array($col,$columns,TRUE)) {//test for column name validity
      $sql.=($ctr?' AND ':' WHERE ')."$col=?";
      $params[$ctr+1]=$val;
      $ctr++;
    }

//sorting
$ctr=0;
if (isset($_GET['sort']) && is_array($_GET['sort'])
  foreach($_GET['sort'] as $col=>$asc)
    if (in_array($col,$columns,TRUE)) {//test for column name validity
      $sql.=($ctr?',':' ORDER BY ')."$col ".($asc?'ASC':'DESC');
      $ctr++;
    }

//execution
$db->exec($sql,$params);

注意:如果列名包含奇怪的字符或空格,则必须引用它们:$db->quote($col)

于 2014-03-18T20:38:18.603 回答