7
تشکر

فیلتر ها در لاراول

Laravel

Laravel

اساسا یک فیلتر مجموعه ای از کدهاست که شما می خواهید قبل یا بعد از درخواست به یک Route اجرا شود تا عملکرد برنامه را تحت تاثیر قرار دهد. همچنین فیلترهای سراسری (Global filters) هم وجود دارند که قبل یا بعد همه درخواست ها اجرا می شوند .

به طور مثال فیلتر اعتبارسنجی کاربران. به اینصورت که پیش از اجرای Route کدهای Before filter اجرا میشود تا ابتدا شما از تمامی فیلترهایی که برای آن Route در نظر گرفته شده است رد شوید و سپس Route برای شما نمایش داده میشود.
در ادامه با ما همراه باشید…

Global Filters

نگاهی به app/filters.php بیاندازید، شما 2 فیلتر مشاهده خواهید کرد. این فیلترها قبل (Before) و یا بعد (After) از هر درخواستی در برنامه تان اجرا می شود که به آنها Global filters یا فیلترهای سراسری گفته می شود. هیچ نیازی به اضافه کردن این فیلترها به Routeها وجود ندارد زیرا آنها به طور پیش فرض برای همه Routeها به اجرا در خواهند آمد.

//app/filters.php
App::before(function($request)
{
	//
});

App::after(function($request, $response)
{
	//
});

Route Filters

برای ایجاد فیلتر جدید، فایل app/filters.php را باز کنید و از متد Route::filter اسفاده نمایید. این متد 2 پارامتر می پذیرد، اولین پارامتر نام فیلتر می باشد و دومین پارامتر Closure است جاییکه شما منطق فیلتر را در آن پیاده سازی می کنید.

خب بیایید اولین فیلتر را بسازیم:

//app/filters.php
  
  //before route
  Route::filter('access_perm', function() {
    if(!Cookie::has('__ne_clivern')) {
      return Redirect::to('404');  //send to 404 route
    }
  });
  
  // after route 
  Route::filter('log', function() {
    //used to save logs
  });

فیلتر اول چک میکند که اگر کاربر کوکی ne_clivern__ را نداشت به صفحه 404 تغییر مسیر دهد در غیر اینصورت Route مورد نظر نشان داده شود، فیلتر دوم هم در اینجا برای ذخیره لاگ استفاده میشود.

بعد از ایجاد فیلترها ، می توانیم آنها را به Routeهایمان نسبت دهیم ؛ تا قبل و یا بعد از Route و یا هر دو به اجرا درآیند.

//app/routes.php
  Route::get('404', function(){
    return '404 Page';
  });

  Route::get('profile',array(
    'before'=>'access_perm',  //add before filter
    'after'=>'log',           //add after filter
    function() {  
      return View::make('hello');  //render app/views/hello.blade.php
    }
  ));

هر Route می تواند چندین فیلتر را بپذیرد. مثال:

Route::get('profile',array(
  'before'=>'access_perm|another_filter',
  function() {
    return View::make('hello');  //render app/views/hello.blade.php
  }
));

//OR
Route::get('profile',array(
  'before' => array('access_perm','another_filter'),
  function() {
    return View::make('hello');  //render app/views/hello.blade.php
  }
));

همانطور که می بینید، کاراکتر | به منظور جدا کردن فیلتر ها استفاده می‌شود و یا می توانید فیلترها را در آرایه قرار دهید.

نکته: در فیلترهای چندگانه اگر اولین فیلتر رد شود تمامی فیلترهای بعدی نیز کنسل می شوند.

Filter Parameters

لاراول مجموعه ای از پارامترها را برای before و after فیلتر فراهم کرده است. اجازه دهید تا نگاهی به این پارامترها بندازیم:

///app/filters.php
 
  //before filter
  Route::filter('access_perm', function($route,$request) {
    var_dump($route);
    var_dump($request);
  });
 
  //after filter
  Route::filter('log', function($route,$request,$response) {
    var_dump($route);
    var_dump($request);
    var_dump($response);
  });

همینطور که میبینید هر دو فیلترهای before و after پارامترهای route$ و request$ را دارند. همینطور فیلتر after یک پارامتر اضافه به نام response$ را دریافت میکند. route$ نمونه ای از آبجکت Illuminate\Routing\Route و request$ نمونه ای از آبجکت Illuminate\Http\Request و response$ نمونه ای از آبجکت Illuminate\Http\Response است.

در مثال زیر، شما می توانید به داده های مربوط به route و request از داخل فیلتر از طریق این پارامترها دسترسی داشته باشید.

//app/routes.php
Route::get('profile/{view}',array(
  'before' =>"change_view",
  function() {
    return 'defualt view';
  }
));

//app/filters.php
Route::filter('change_view', function($route,$request) {
  if(in_array($route->getParameter('view'), array('first','second','third'))) {
    return $route->getParameter('view');
  }
});

Filter Classes

به منظور Filtering پیشرفته، لاراول این امکان را به شما میدهد که کلاس‌هایی بسازید و فیلتر‌های خودتان را در آنجا قرار بدهید. شما ممکن است کلاسهای فیلتر را در دایرکتوری موجود ذخیره کنید اما بهتر است که یک پوشه جدا بسازید مثل app/filters و کلاسهای فیلتر را درون آن ذخیره کنیم. برای اینکار ابتدا ما نیاز داریم که دایرکتوری app/filters را به classmap درون فایل composer.json در روت پروژه اضافه کنیم.

"classmap": [
  "app/commands",
  "app/controllers",
  "app/models",
  "app/database/migrations",
  "app/database/seeds",
  "app/tests/TestCase.php",
  "app/filters"
]

بعد از اینکار دستور composer dump-autoload را در روت پروژه انجام دهید.

حالا آماده ایم تا اولین کلاس فیلتر را بسازیم(AppFilters.php).

//app/filters/AppFilters.php
class ChangeViewFilter {
  public function filter($route, $request) {
    if (in_array($route->getParameter('view'), array('first', 'second', 'third'))) {
      return $route->getParameter('view');
    }
  }
}

سپس از فیلتری که در بالا نوشتیم میتوانیم در Routeها به صورت زیر استفاده کنیم:

//app/filters.php
Route::filter('change_view', 'ChangeViewFilter');

//app/routes.php
Route::get('test/{view}',array(
  'before' =>"change_view",
  function(){
    return 'default view';
  }
));

Pattern Filters

Pattern filters جهت اجرای فیلتر بر روی یکسری Routeها که با الگویی از کلمات مشخص شده‌اند به کار می‌رود. برای مثال اگر می‌خواهید یک فیلتر برای همه‌ی Routeهایی که با /users شروع میشوند مثل users/create یا {users/update/{$id اجرا شود، از الگوی فیلتر */users بایستی استفاده کنید.

//app/routes.php
Route::when('users/*', 'test_filter');

Group Filters

استفاده از Pattern filters که پیشتر گفته شد زمانی مفید است که بخواهید یک مجموعه از Routeهای مشخص را تحت تاثیر قرار بدهید. مثل مثال بالا:

اما اگر بخواهید یک فیلتر را برای مجموعه‌ای از Routeهایی که هیچ ارتباطی بهم ندارند به کار ببندید به جای اینکه برای هر کدام از Routeها یک Pattern تعریف کنید بهتر است که از گروهبندی استفاده کنید. مانند مثال زیر:

Route::group(array('before' => 'auth'), function()
{
  Route::get('user/account', 'UserController@account');
  Route::get('user/settings', 'UserController@settings');
  Route::get('post/create', 'PostController@create');
  Route::post('post/store', 'PostController@store');
  // ...
});

در این مثال برای همه Routeهای داخل گروه به طور اتوماتیک فیلتر اعتبارسنجی، اجرا می‌شود.

  • امیرحسین می‌گه:

    ممنون زحمت کشیدی، واقعاً خوب بود

    فقط قسمت Filter Parameters رو خوب باز نکردی

    در کل واقعاً ممنون کم کم خوب داری تخصصیش می کنی

    در مورد IoC Container هم کم کم یه مجموعه خوب اگه وقت کردی آماده کن خیلی مفصله بحثش

  • عالی بود
    خیلی خیلی ممنون

  • با اون که سر در نیاوردم اما عالی بود


  • نظرات این مطلب بسته است.