php 具有多个条件的 Laravel 搜索查询

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24852704/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 17:30:36  来源:igfitidea点击:

Laravel search query with multiple conditions

phplaravel-4

提问by rommel109g

Newbie to PHP/Laravel here so please be patient.

PHP/Laravel 新手,请耐心等待。

I have a webpage that is searching based on 3 criteria for dogs , breed, sex and radius.

我有一个网页,它根据狗、品种、性别和半径的 3 个标准进行搜索。

here is the relevant code:

这是相关的代码:

search page

搜索页面

<div class="col-md-12 zero-pad-left zero-pad-right"> 
{{ Form::open(array('action' => array('DogsController@index'), 'class'=>'form width88', 'role'=>'search', 'method' => 'GET')) }} 
<div id="prefetch">
  {{ Form::text('search-breed', null, array('class' => 'typeahead form-group form-control', 'placeholder' => 'Search by breed here...')) }}
  {{ Form::text('sex', null, array('class' => 'form-group form-control', 'placeholder' => 'Search by sex here...')) }}
  {{ Form::text('miles', null, array('class' => 'form-group form-control', 'placeholder' => 'Search by distance here...')) }}




</div>
{{ Form::submit('Search', array('class' => 'btn btn-default search-bar-btn')) }}
{{ Form::close() }} 

ControllerPage

控制器页面

class DogsController extends \BaseController {

public function __construct()
{
    // call base controller constructor
    parent::__construct();

    // run auth filter before all methods on this controller except index and show
    $this->beforeFilter('auth', array('except' => array('show')));
}

/**
 * Display a listing of the resource.
 *
 * @return Response
 */
public function index()
{
    if (Input::has('search')) {
        $queryString = Input::get('search');
        $dogs = Dog::where('name', 'LIKE', "%$queryString%")->orderBy('name')->paginate(5);
    }

    elseif (Input::has('search-breed')) 
    {
        $dogs = Dog::whereHas('breed', function($q)     
        {
            $queryString = Input::get('search-breed');
            $q->where('name', 'LIKE', "%$queryString%");

        })->orderBy('name')->paginate(5);

    } //end elseif

    else {
        $dogs = Dog::orderBy('name')->paginate(5);
        } //end else

    return View::make('dogs.index')->with(array('dogs' => $dogs));
} //end function index()

when i enter a search for poodle, male, within 20 miles, the url shows as follows:

当我搜索 20 英里内的贵宾犬时,网址显示如下:

http://ruff-love.dev/dogs?search-breed=poodle&sex=M&miles=20

The search currently works ok when searching for just breed.

当只搜索品种时,搜索目前工作正常。

I cant seem to figure out the syntax to add the SEX and RADIUS criteria also. it should allow for those criteria to be null and still perform the query.

我似乎也无法弄清楚添加 SEX 和 RADIUS 标准的语法。它应该允许这些条件为空并仍然执行查询。

any advice would be greatly apprecaited

任何建议将不胜感激

回答by Jarek Tkaczyk

You can use query scopes http://laravel.com/docs/eloquent#query-scopesto make it verbose and easier in your controller (or wherever you will be doing it in future) then chain them according to your needs:

您可以使用查询范围http://laravel.com/docs/eloquent#query-scopes使其在您的控制器(或您将来要做的任何地方)中变得冗长和容易,然后根据您的需要链接它们:

// Dog model
public function scopeSearchBreed($query, $breed)
{
  $query->whereHas('breed', function ($q) use ($breed) {
    $q->where('name', 'like', "%{$breed}%");
  });
}

public function scopeWithinRadius($query, $radius)
{
  $query->where(...); // do math here
}

Then all you need is this:

那么你所需要的就是这个:

public function index()
{
  $q = Dog::query();

  if (Input::has('search'))
  {
     // simple where here or another scope, whatever you like
     $q->where('name','like',Input::get('search'));
  }

  if (Input::has('search-breed'))
  {
     $q->searchBreed(Input::get('search-breed'));
  }

  if (Input::has('sex'))
  {
     $q->where('sex', Input::get('sex'));
  }

  if (Input::has('radius'))
  {
     $q->withinRadius(Input::get('radius'));
  }

  $dogs = $q->orderBy(..)->paginate(5);

  // ...

回答by Dave Morrissey

Here's one possible solution, I think there are probably others. Create an empty query builder with the query()function and add the non-null clauses to it, then call the paginate()function at the end.

这是一种可能的解决方案,我认为可能还有其他解决方案。使用该query()函数创建一个空的查询构建器并向其添加非空子句,然后paginate()在最后调用该函数。

$builder = Dogs::query();
if (Input::has('search')) {
    $queryString = Input::get('search');
    $builder->where('name', 'LIKE', "%$queryString%");
}
// ... more clauses from the querystring
$dogs = $builder->orderBy('name')->paginate(5);

回答by M.J

$builder = Dogs::query();
$term = Request::all();
if(!empty($term['breed'])){
    $builder->where('breed','=',$term['breed']);
}
if(!empty($term['sex'])){
    $builder->where('sex','=',$term['sex']);
}
if(!empty($term['radius'])){
    $builder->where('radius','=',$term['radius']);
}

$result = $builder->orderBy('id')->get();