首页 > 解决方案 > 带有 Ajax 的 PDO 过滤系统。有没有更好的办法?

问题描述

我正在尝试使用选择框过滤用户的一些输入。我正在考虑是否有更好的方法来做到这一点。

    if(isset($_POST['action']))
    {
        
        $sql = "SELECT * FROM occasions WHERE naam IS NOT NULL";
        
        if(isset($_POST['merk'])){
            
            $merk = $_POST['merk'];
            
            $merkQuery = implode(',', array_fill(0, count($merk), '?'));
            
            $sql .= " AND merk IN(".$merkQuery.")";
        }
        
        if(isset($_POST['brandstof'])){
            
            $brandstof = $_POST['brandstof'];
            
            $brandstofQuery = implode(',', array_fill(0, count($brandstof), '?'));
            
            $sql .= " AND brandstof IN(".$brandstofQuery.")";
        }
        
        
        //We prepare our SELECT statement.
        $statement = $pdo->prepare($sql);
        
        
        
        if(isset($_POST['merk'])){
            //Execute statement.
            $statement->execute(array_merge(array_values($merk)));
        }

        if(isset($_POST['brandstof'])){
            //Execute statement.
            $statement->execute(array_merge(array_values($brandstof)));
        }
        
        if(isset($_POST['merk']) && isset($_POST['brandstof']))
        {
            $statement->execute(array_merge(array_values($merk), array_values($brandstof)));
        }
        else
        {
            $statement->execute();
        }
   }

因为如果有很多选择框需要过滤,代码会变长。我想知道是否有更好的方法来过滤多个选择框。

这是一个例子:链接

标签: phpajaxfilterpdo

解决方案


我建议重命名 post 变量;将它们分组为一个二维数组。

<input type="checkbox" name="data[merk][bmw]" />
<input type="checkbox" name="data[merk][skoda] />

等等。

这是做什么的,它允许您使用 foreach 来遍历检查的任何值。

$data = $_POST['data'] ?? []; // null coalesce defaults to a blank array if post var is null
foreach($data as $category=>$val) {
    settype($val, 'array');
    $query = implode(',', array_fill(0, count($val), '?'));
    foreach($val as $k=>$v) {
        $params[] = $k;
    }

    // DON'T DO THIS!
    $sql .= " AND $category IN(".$query.")";
}

您不应该这样做的原因是因为您永远不应该使用用户提供的数据构建查询。

但是,您可以做的是将用户提供的数据与硬编码数据进行映射。

$map = [
    // form value => db field
    'merk'      => 'MERK',
    'brandstof' => 'BRANDSTOF',
    // ... etc
];

然后在构建查询时,

$sql .= " AND $map[$category] IN($query)";

与此同时,您已经在$params.

——

最重要的是,我们所做的是重构代码,因为我们注意到事情正在重复。例如,您不得不为每个场合重复代码(?)。一种解决方案是继续检查每个 post 值并调用函数来计算 ?s。但即便如此,输入所有这些isset()s 也是重复的。


回想起来,做这样的输入可能会更好:

<input type="checkbox" name="data[merk][]" value="bmw" />
<input type="checkbox" name="data[merk][]" value="skoda" />

这无疑会更直观,尽管您仍然需要构建 params 数组。

foreach($val as $v) {
    $params[] = $v;
}

推荐阅读