【问题标题】:PDO filter system with Ajax. Is there a better way?带有 Ajax 的 PDO 过滤器系统。有没有更好的办法?
【发布时间】:2021-04-14 10:32:45
【问题描述】:

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

    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();
        }
   }

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

这里是一个例子:link

【问题讨论】:

  • 是的,有更好的方法
  • 我们能看到您尝试执行的准备好的查询吗?
  • 如果您的选择被命名为name="data[brand]" 等,那么您只需传递$_POST['data']。但是对于您的场景,准备是不同的。所以也许可以使用data 下的键。
  • @RiggsFolly 我现在已经添加了准备好的查询
  • 现在更有意义了

标签: php ajax filter pdo


【解决方案1】:

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

<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;
}

【讨论】:

  • 所以这个替代方案不需要 array_merge 函数?当用户一起输入值时,过滤系统是否仍然有效?
  • 当我说每次用户输入一个值时,我是否正确理解了这一点,它会循环并为每个值提供一个参数?然后在循环之后我应该说 $statement->execute($params) ?那么有多少输入就无所谓了?
  • 这不是我的想法,而是在我的手机上输入的;我没有办法验证它。但想法是您正在按照与查询相同的顺序构建参数列表。因此,除非您的查询在这些参数之前或之后有其他参数,否则不需要合并。
  • foreach 只会遍历它给出的任何内容。
  • 我应该改变使用 AJAX 将值传递给 PHP 的方式吗? var action = '数据'; var merk = get_filter_text('merk'); varbrandstof = get_filter_text('brandstof'); var carrosserie = get_filter_text('carrosserie'); $.ajax({ url: 'php_file', method: 'POST', data: { action: action, merk: merk,brandstof:brandstof, carrosserie: carrosserie }, ...
猜你喜欢
  • 1970-01-01
  • 2013-04-13
  • 1970-01-01
  • 2016-09-17
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 2015-11-02
  • 1970-01-01
相关资源
最近更新 更多