通过Laravel中的特征搜索多个列

时间:2017-08-11 07:09:33

标签: php laravel laravel-5.4

结帐this tutorial我正在我的Laravel 5.4申请中实施搜索网址。我已经在我的模型中实现了一个特性,例如,如果我有公司模型,那么在模型中,我包括我的特征:

class Company extends Model
{
    use SoftDeletes, DataViewer;

    protected $fillable = [
        'name', 'address', 'city', 'state', 'country', 'type', 'sub_type',
    ];

    public static $columns = [
        'name', 'address', 'city', 'type', 'sub_type'
    ];
}

现在我有这样的DataViewer特征:

trait DataViewer {

    protected $operators = [
        'equal' => '=',
        'not_equal' => '<>',
        'less_than' => '<',
        'greater_than' => '>',
        'less_than_or_equal_to' => '<=',
        'greater_than_or_equal_to' => '>=',
        'in' => 'IN',
        'like' => 'LIKE'
    ];

    public function scopeSearchPaginateAndOrder($query)
    {
        $request = app()->make('request');

        return $query
            ->orderBy($request->column, $request->direction)
            ->where(function($query) use ($request) {
                if($request->has('search_input')) {
                    if($request->search_operator == 'in') {
                        $query->whereIn($request->search_column, explode(',', $request->search_input));
                    } else if($request->search_operator == 'like') {
                        $query->where($request->search_column, 'LIKE', '%'.$request->search_input.'%');
                    }
                    else {
                        $query->where($request->search_column, $this->operators[$request->search_operator], $request->search_input);
                    }
                }
            })
            ->paginate($request->per_page);
    }

}

我在控制器中称之为:

public function getData()
{
    $models = Company::searchPaginateAndOrder();
    return response()->json([
        'model' => $models
    ]);
}

为了达到这个目的,我正在调用这样的URL:

http://stellar.dev/api/companies?column=name&direction=asc&page=1&per_page=50&search_column=name&search_operator=like&search_input=icici

我在这里遇到的问题是它只能通过一列搜索,我想在一个查询中搜索多列。建议我可以做些什么。

感谢。

1 个答案:

答案 0 :(得分:1)

您应该将查询字符串作为多个列的数组,如下所示。

http://stellar.dev/api/companies?column=name&direction=asc&page=1&per_page=50&search_column[]=name&search_operator[]=like&search_input[]=icici&search_column[]=lastname&search_operator[]=like&search_input[]=asd

然后读取并将它们用作数组。您还需要检查它们的长度以防止意外错误。然后,您可以简单地使用一个简单的循环来连接您的条件,如下面的代码块。

trait DataViewer {

    protected $operators = [
        'equal' => '=',
        'not_equal' => '<>',
        'less_than' => '<',
        'greater_than' => '>',
        'less_than_or_equal_to' => '<=',
        'greater_than_or_equal_to' => '>=',
        'in' => 'IN',
        'like' => 'LIKE'
    ];

    public function scopeSearchPaginateAndOrder($query)
    {
        $request = app()->make('request');
        $searchInputs = $request->get('search_input', []);
        $searchOperators = $request->get('search_operator', []);
        $searchColumns = $request->get('search_column', []);

        $query->orderBy($request->column, $request->direction);

        if(count($searchInputs) == count($searchOperators) && count($searchOperators) == count($searchColumns)) {
            $query->where(function($query) use ($searchInputs, $searchOperators, $searchColumns) {
                for($x = 0, $l = count($searchColumns); $x < $l; $x++){
                    if($searchOperators[$x] == 'in') {
                       $query->whereIn($searchColumns[$x], explode(',', $searchInputs[$x]));
                   } else if($searchOperators[$x] == 'like') {
                        $query->where($searchColumns[$x], 'LIKE', "%{$searchInputs[$x]}%");
                   }
                    else {
                       $query->where($searchColumns[$x], $searchColumns, $searchInputs[$x]);
                   }
               }
           });
        }

        return $query->paginate($request->per_page);
    }

}

注意:我强烈建议您在此搜索页面上使用post动词,否则您的数据将被html编码,并且您的网址绝对不是用户友好的。

已编辑的答案

我已经更改了多个列的代码,单个运算符和单个字段。

public function scopeSearchPaginateAndOrder($query)
    {
        $request = app()->make('request');
        $searchInput = $request->get('search_input');
        $searchOperator = $request->get('search_operator');
        $searchColumns = $request->get('search_column', []);

        $query->orderBy($request->column, $request->direction);

        if(count($searchColumns) > 0) {
            $query->where(function($query) use ($searchInput, $searchOperator, $searchColumns) {
                for($x = 0, $l = count($searchColumns); $x < $l; $x++){
                    if($searchOperator == 'in') {
                        $query->whereIn($searchColumns[$x], explode(',', $searchInput));
                    } else if($searchOperator == 'like') {
                        $query->where($searchColumns[$x], 'LIKE', "%{$searchInput}%");
                    }
                    else {
                        $query->where($searchColumns[$x], $searchOperator, $searchInput);
                    }
                }
            });
        }

        return $query->paginate($request->per_page);
    }