Laravel:查询字符串到Eloquent过滤器

时间:2014-08-02 01:25:35

标签: php laravel-4 eloquent

我需要一个小函数来获取查询字符串并将其转换为3个查询之一:

  • WHERE列BETWEEN值和值
  • WHERE column = value
  • WHERE列(值,值,...)

这是我目前正在做的事情:

// USE: ?price[between][min]=0&price[between][max]=100&size[in][value]=L&size[in][value]=M

$filters = ['price', 'size'];

$products= Product::query();

foreach($filters as $filter)
{
    if(isset($input[$filter]) && array_filter($input[$filter][key($input[$filter])]))
    {
        sort($input[$filter][key($input[$filter])]);
        $products->{'where' . ucfirst(key($input[$filter]))}($filter, $input[$filter][key($input[$filter])]);
    }
}

return $products->get();

以下是我的问题:

  1. 这是一个好方法吗?如果是这样,哪个地方适合这种逻辑呢?
  2. 是否已经有一个包来处理这个逻辑?
  3. 如果上述两者都没有,那么实现这一目标的最佳途径是什么?

1 个答案:

答案 0 :(得分:0)

  1. 我会简化一些事情。至于这个地方,我会把它放在ProductRepository中(如果你使用Repository Pattern)。如果你不这样做,我会把它放在模型里面的一个函数中。
  2. 我不知道。哈文看不到任何东西,但我不是在找这样的东西。
  3. 就个人而言,最好的方法是在存储库中创建一个函数,简化查询字符串和代码。
  4. 您可能对该查询字符串有一些问题,因为var_dump会导致:

    array(2) {
        'price' =>
        array(1) {
            'between' =>
            array(2) {
                'min' => string(1) "0"
                'max' => string(3) "100"
            }
        }
        'size' =>
        array(1) {
            'in' =>
            array(1) {
                'value' => string(1) "M"
            }
        }
    }
    

    您发现变量L的值size已丢失,因为它已替换为M。当然,你可以添加另一个数组,但如果你可以简化为这样的事情:

    ?price[between]=0,100&size[in]=L,M
    

    在任何情况下,出于可读性目的,我更喜欢这段代码。

    $qString = Input::all();
    
    $model = App::make('Product');
    
    $products = $model->where(function($query) use($qString) {
        foreach($qString as $column => $operations) {
            foreach($operations as $operator => $values) {
                switch($operator) {
                    case 'between': 
                        $query->whereBetween($column, array($values['min'], $values['max']));
                        break;
                    case 'in': 
                        $query->whereIn($column, $values);
                        break;
                }
                // or replace the switch with this:
                // $query->{'where' . ucfirst($operator)}($column, $values);
            }
        }
    })->get(); 
    

    请注意,这尚未经过测试(虽然我在我的Repository方法中使用了闭包并且它们有效),您可能需要稍微调整一下。

    另外请注意,如果您选择我建议的查询字符串,您可能需要一些验证。