QueryFilter: рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдореЙрдбрд▓ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛

рдореИрдВ URL- рдЕрдиреБрд░реЛрдз рджреНрд╡рд╛рд░рд╛ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдХреЗ рдЖрдпреЛрдЬрди рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЛ рдЖрдкрдХреЗ рдзреНрдпрд╛рди рдореЗрдВ рд▓рд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореИрдВ PHP рднрд╛рд╖рд╛ рдФрд░ рд▓рд╛рд░рд╡реЗрд▓ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛ред

рд╕рдВрдХрд▓реНрдкрдирд╛


рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ QueryFilter рд╡рд░реНрдЧ рдмрдирд╛рдиреЗ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИред

GET /posts?title=source&status=active 

рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдорд╛рдирджрдВрдбреЛрдВ рджреНрд╡рд╛рд░рд╛ рдкрджреЛрдВ (рдкреЛрд╕реНрдЯ рдореЙрдбрд▓) рдХреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░реЗрдВрдЧреЗ:

  • рд╢реАрд░реНрд╖рдХ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ "рд╕реНрд░реЛрдд" рд╢рдмреНрдж рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐;
  • рдореВрд▓реНрдп "рдкреНрд░рдХрд╛рд╢рд┐рдд" рд╕реНрдерд┐рддрд┐ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ;

рдЖрд╡реЗрджрди рдЙрджрд╛рд╣рд░рдг


рдкреЛрд╕реНрдЯ рдореЙрдбрд▓

 <?php namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model { /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'name', 'id', 'title', 'slug', 'status', 'type', 'published_at', 'updated_at', ]; } 

рдПрдХ рдорд╛рд░реНрдЧ рдЬреЛрдбрд╝реЗрдВ:

 Route::get('/posts', 'PostController@index'); 

JSON рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдЖрдЙрдЯрдкреБрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрд╕рд╛рдзрди \ Post рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдБ:

 namespace App\Http\Resources; use Illuminate\Http\Resources\Json\JsonResource; class Post extends JsonResource { /** * Transform the resource into an array. * * @param \Illuminate\Http\Request $request * @return array */ public function toArray($request) { return [ 'id' => $this->ID, 'title' => $this->post_title, 'slug' => $this->post_name, 'status' => $this->post_status, 'type' => $this->post_type, 'published_at' => $this->post_date, 'updated_at' => $this->post_modified, ]; } } 

рдФрд░ рдирд┐рдпрдВрддреНрд░рдХ рдПрдХ рд╣реА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рд╕рд╛рде:

 namespace App\Http\Controllers; use App\Http\Resources\Post as PostResource; use App\Post; class PostController extends Controller { /** * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection */ public function index() { $posts = Post::limit(10)->get(); return PostResource::collection($posts); } } 

рдорд╛рдирдХ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рджреНрд╡рд╛рд░рд╛ рдЖрдпреЛрдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

 /** * @param Request $request * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection */ public function index(Request $request) { $query = Post::limit(10); if ($request->filled('status')) { $query->where('post_status', $request->get('status')); } if ($request->filled('title')) { $title = $request->get('title'); $query->where('post_title', 'like', "%$title%"); } $posts = $query->get(); return PostResource::collection($posts); } 

рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде, рд╣рдореЗрдВ рдирд┐рдпрдВрддреНрд░рдХ рдХреА рд╡реГрджреНрдзрд┐ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИ, рдЬреЛ рдЕрд╡рд╛рдВрдЫрдиреАрдп рд╣реИред

QueryFilter рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛


рдЗрд╕ рддрд░рд╣ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рдХрд╛ рдЕрд░реНрде рдкреНрд░рддреНрдпреЗрдХ рдЗрдХрд╛рдИ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ рдЬреЛ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреНрдпреЗрдХ рдХреНрд╖реЗрддреНрд░ рдХреЗ рддрд░реАрдХреЛрдВ рдХрд╛ рдорд╛рдирдЪрд┐рддреНрд░рдг рдХрд░рддрд╛ рд╣реИред

рдЕрдиреБрд░реЛрдз рджреНрд╡рд╛рд░рд╛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░реЗрдВ:

 GET /posts?title=source&status=publish 

рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкреЛрд╕реНрдЯрдлрд╝рд┐рд▓реНрдЯрд░ рдХреНрд▓рд╛рд╕ рдФрд░ рд╢реАрд░реНрд╖рдХ () рдФрд░ рд╕реНрдерд┐рддрд┐ () рд╡рд┐рдзрд┐рдпрд╛рдБ рд╣реЛрдВрдЧреА ред PostFilter рдЕрдореВрд░реНрдд рд╡рд░реНрдЧ QueryFiler рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░реЗрдЧрд╛ рдЬреЛ рдкрд╛рд░рд┐рдд рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рд╡рд░реНрдЧ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рдорд┐рд▓рд╛рди рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред

рд╡рд┐рдзрд┐ рд▓рд╛рдЧреВ ()

QueryFIlter рд╡рд░реНрдЧ рдореЗрдВ рдПрдХ рд▓рд╛рдЧреВ () рд╡рд┐рдзрд┐ рд╣реИ, рдЬреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╝рд┐рдореНрдореЗрджрд╛рд░ рд╣реИ рдЬреЛ PostFilter рдмрдЪреНрдЪреЗ рд╡рд░реНрдЧ рдореЗрдВ рд╣реИрдВред

 namespace App\Http\Filters; use Illuminate\Database\Eloquent\Builder; use Illuminate\Http\Request; abstract class QueryFilter { /** * @var Request */ protected $request; /** * @var Builder */ protected $builder; /** * @param Request $request */ public function __construct(Request $request) { $this->request = $request; } /** * @param Builder $builder */ public function apply(Builder $builder) { $this->builder = $builder; foreach ($this->fields() as $field => $value) { $method = camel_case($field); if (method_exists($this, $method)) { call_user_func_array([$this, $method], (array)$value); } } } /** * @return array */ protected function fields(): array { return array_filter( array_map('trim', $this->request->all()) ); } } 

рд▓рдмреНрдмреЛрд▓реБрдЖрдм рдпрд╣ рд╣реИ рдХрд┐ рдЕрдиреБрд░реЛрдз рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд╛рд░рд┐рдд рдкреНрд░рддреНрдпреЗрдХ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЪрд╛рдЗрд▓реНрдб рдлрд╝рд┐рд▓реНрдЯрд░ рдХреНрд▓рд╛рд╕ (рдкреЛрд╕реНрдЯрдлрд╝рд┐рд▓реНрдЯрд░ рдХреНрд▓рд╛рд╕) рдореЗрдВ рдПрдХ рдЕрд▓рдЧ рд╡рд┐рдзрд┐ рд╣реИред рдпрд╣ рд╣рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рд┐рд▓реНрдЯрд░ рдлрд╝реАрд▓реНрдб рдХреЗ рд▓рд┐рдП рддрд░реНрдХ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

рдкреЛрд╕реНрдЯрдлрд┐рд▓реНрдЯрд░ рдХреНрд▓рд╛рд╕

рдЕрдм рдЪрд▓рд┐рдП PostFilter рдХреНрд▓рд╛рд╕ рдмрдирд╛рдиреЗ рдХреА рдУрд░ рдмрдврд╝рддреЗ рд╣реИрдВ рдЬреЛ QueryFilter рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддреА рд╣реИ ред рдЬреИрд╕рд╛ рдХрд┐ рдкрд╣рд▓реЗ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕ рд╡рд░реНрдЧ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рд╡рд┐рдзрд┐рдпрд╛рдБ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП рдЬрд┐рдирдХреЗ рджреНрд╡рд╛рд░рд╛ рд╣рдореЗрдВ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░рдирд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╢реАрд░реНрд╖рдХ ($ рдореВрд▓реНрдп) рдФрд░ рд╕реНрдерд┐рддрд┐ ($ рдореВрд▓реНрдп) рддрд░реАрдХреЗ

 namespace App\Http\Filters; use Illuminate\Database\Eloquent\Builder; class PostFilter extends QueryFilter { /** * @param string $status */ public function status(string $status) { $this->builder->where('post_status', strtolower($status)); } /** * @param string $title */ public function title(string $title) { $words = array_filter(explode(' ', $title)); $this->builder->where(function (Builder $query) use ($words) { foreach ($words as $word) { $query->where('post_title', 'like', "%$word%"); } }); } } 

рдпрд╣рд╛рдВ рдореБрдЭреЗ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд┐ рдХреЗ рд╡рд┐рд╕реНрддреГрдд рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдХрд╛рд░рдг рдирд╣реАрдВ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИ, рдХрд╛рдлреА рдорд╛рдирдХ рдкреНрд░рд╢реНрдиред рдореБрджреНрджрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкреНрд░рддреНрдпреЗрдХ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рд╡рд┐рдзрд┐ рд╣реИ рдФрд░ рд╣рдо рдЕрдиреБрд░реЛрдз рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рднреА рддрд░реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рджрд╛рдпрд░реЗ рдмрдирд╛рдПрдБ ()

рдЕрдм рд╣рдореЗрдВ рдореЙрдбрд▓ рдФрд░ рдХреНрд╡реЗрд░реА рдбрд┐рдЬрд╝рд╛рдЗрдирд░ рдХреЛ рдмрд╛рдВрдзрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ

 /** * @param Builder $builder * @param QueryFilter $filter */ public function scopeFilter(Builder $builder, QueryFilter $filter) { $filter->apply($builder); } 

рдЦреЛрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЕрдкрдиреЗ рдорд╛рдорд▓реЗ PostFilter рдореЗрдВ рдлрд╝рд┐рд▓реНрдЯрд░ () рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдФрд░ QueryFilter рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкрд╛рд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ ред

 $filteredPosts = Post::filter($postFilter)->get(); 

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╕рднреА рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рд▓реЙрдЬрд┐рдХ рдХреЛ рдлрд╝рд┐рд▓реНрдЯрд░ ($ рдкреЛрд╕реНрдЯрдлрд╝рд┐рд▓реНрдЯрд░) рд╡рд┐рдзрд┐ рд╕реЗ рдХреЙрд▓ рдХрд░рдХреЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдирд┐рдпрдВрддреНрд░рдХ рдХреЛ рдЕрдирд╛рд╡рд╢реНрдпрдХ рддрд░реНрдХ рд╕реЗ рдмрдЪрд╛рдпрд╛ рдЬрд╛ рд╕рдХреЗред

рдкреБрди: рдЙрдкрдпреЛрдЧ рдХреА рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рдЖрдк рд╕реНрдХреЛрдк рдореЗрдВ рд╕реНрдХреЛрдкрдлрд┐рд▓реНрдЯрд░ рд╡рд┐рдзрд┐ рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдкреНрд░рддреНрдпреЗрдХ рдореЙрдбрд▓ рдХреЗ рд▓рд┐рдП рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред

 namespace App\Http\Filters; use Illuminate\Database\Eloquent\Builder; trait Filterable { /** * @param Builder $builder * @param QueryFilter $filter */ public function scopeFilter(Builder $builder, QueryFilter $filter) { $filter->apply($builder); } } 

рдкреЛрд╕реНрдЯ рдРрдб рдореЗрдВ:

 class Post extends CorcelPost { use Filterable; 

рдпрд╣ рдХрдВрдЯреНрд░реЛрд▓рд░ рд╡рд┐рдзрд┐ рдореЗрдВ рдЗрдВрдбреЗрдХреНрд╕ () рдХреЛ рдкреЛрд╕реНрдЯрдлрд┐рд▓реНрдЯрд░ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реИ рдФрд░ рдлрд╝рд┐рд▓реНрдЯрд░ () рдореЙрдбрд▓ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИред

 class PostController extends Controller { /** * @param PostFilter $filter * @return \Illuminate\Http\Resources\Json\ResourceCollection */ public function index(PostFilter $filter) { $posts = Post::filter($filter)->limit(10)->get(); return PostResource::collection($posts); } } 

рд╡рд╣ рд╕рдм рд╣реИред рд╣рдо рд╕рднреА рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рд▓реЙрдЬрд┐рдХ рдХреЛ рдЙрдкрдпреБрдХреНрдд рд╡рд░реНрдЧ рдореЗрдВ рд▓реЗ рдЧрдП, рдЬреЛ рдПрдХрд▓ рдЬрд┐рдореНрдореЗрджрд╛рд░реА рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдХрд╛ рдкрд╛рд▓рди рдХрд░ рд░рд╣рд╛ рд╣реИ (рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреА рдареЛрд╕ рдкреНрд░рдгрд╛рд▓реА рдореЗрдВ рдПрд╕)

рдирд┐рд╖реНрдХрд░реНрд╖


рдлрд┐рд▓реНрдЯрд░ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЖрдкрдХреЛ рдЯреНрд░реЗрд▓рд░ рдкрддрд▓реЗ рдирд┐рдпрдВрддреНрд░рдХ рд╕реЗ рдЪрд┐рдкрдХреЗ рд░рд╣рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдФрд░ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓реЗрдЦрди рдХреА рд╕реБрд╡рд┐рдзрд╛ рднреА рджреЗрддрд╛ рд╣реИред

рдпрд╣рд╛рдБ PHP рдФрд░ Laravel рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдХрд╣рд╛, рдпрд╣ рдПрдХ рдЕрд╡рдзрд╛рд░рдгрд╛ рд╣реИ рдФрд░ рдХрд┐рд╕реА рднреА рднрд╛рд╖рд╛ рдпрд╛ рдврд╛рдВрдЪреЗ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддреА рд╣реИред

рд╕рдВрджрд░реНрдн


Source: https://habr.com/ru/post/hi485520/


All Articles