کانال بله, جهت پشتیبانی و اطلاع رسانی کانال بله, جهت پشتیبانی و اطلاع رسانی
عضویت

آموزش HTTP Controllers در لاراول

HTTP Controllers

فهرست محتوا

  1. مقدمه
  2. کنترلرهای پایه
  3. Controller middleware
  4. ساخت کنترلرهای RESTful
    • Partial Resource Routes (تعریف route های منبع به صورت اختصاصی)
    • نام گذاری Resource Route ها
    • ایجاد Resourceهای تودرتو
    • افزودن Route های اضافی بر سازمان به کنترلرهای منبع
  5. کنترلرهای ضمنی (implicit controllers)
  6. dependency injection و کنترلرها
  7. ذخیره موقت route ها در حافظه ی نهان (Route caching)

مقدمه

بجای اینکه کل منطق مدیریت درخواست ها را در یک فایل واحدroutes.php تعریف کنید، ممکن است مایلید باشید این رفتار یا مکانیزم را به وسیله ی کلاس های Controller انجام دهید. کنترلرها می توانند منطق مدیریت درخواست های HTTP مربوط به هم را در یک کلاس گروه بندی کنند. کنترلرها معمولا در پوشه ی routes.php ذخیره می شوند.

کنترلرهای پایه

در زیر مثالی از یک کلاس ساده ی کنترلر را مشاهده می کنید. کلیه ی کنترلرهای Laravel باید از کلاس کنترلر پایه که در فایل های پیش فرض نصب شده لاراول ارائه می شوند، ارث بری کنند:

<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
   /**
    * Show the profile for the given user.
    *
    * @param int $id
    * @return Response
    */
   public function showProfile($id)
   {
       return view('user.profile', ['user' => User::findOrFail($id)]);
   }
}

می توان به صورت زیر به متد action یک کنترلر مسیردهی کرد:

                    Route::get('user/{id}', 'UserController@showProfile');

اگر یک درخواست با URI مسیر (route) مشخص مطابقت داشت، متد showProfile بر روی کلاس UserController فراخوانی می شود. لازم به گفتن نیست که پارامترهای route نیز به متد ارسال می شوند.

Controller ها و namespace ها

دقت داشته باشید که در زمان تعریف route کنترلر، لزومی نداشت namespace آن کنترلر را به صورت کامل معرفی کنیم. بلکه تنها آن بخشی از اسم کلاس را که پس از root فضای نام App\Http\Controllers قرار می گرفت را مشخص می کردیم. به صورت پیش فرض،RouteServiceProvider فایل routes.php را درون route گروه بندی شده که دربردارنده ی فضای نام root controller می باشد، بارگذاری می کند.
اگر بخواهید کنترلرها را به وسیله ی namespace های PHP در subfolder های جدا و گروه بندی شده در پوشه ی App\Http\Controllers به صورت تودرتو سازمان دهی یا جای گذاری کنید، در آن صورت کافی است اسم کلاس مشخص را نسبت به App\Http\Controllers که فضای نام ریشه (root namespace) می باشد، بکار ببرید. بنابراین در صورتی که آدرس کامل کلاس App\Http\Controllers\Photos\AdminController باشد، یک route را به صورت زیر ثبت یا ایجاد می کنیم:

                    Route::get('foo', 'Photos\AdminController@method');

نام گذاری Route های کنترلر

همانند Closure route ها، می توانید به route های کنترلرها اسم تخصیص دهید:

                    Route::get('foo', ['uses' => 'FooController@method', 'as' => 'name']);

ایجاد URL برای متدهای اکشن کنترلر

می توان به وسیله ی متد کمکی route یک URL برای route نام گذاری شده ایجاد کرد:

                    $url = route('name');

همچنین می توان از متد کمکی action برای ایجاد URL به متدهای اکشن کنترلر استفاده کرد. برای این منظور می توان اسم کلاس و متد کنترلر را به تابع کمکی ذکر شده به عنوان آرگومان پاس داد. یادآور می شویم که بخش مربوط به اسم کلاس کنترلر را که بعد از فضای نامApp\Http\Controllers می آید به متد پاس دهید کافی است و لزومی ندارد آدرس کامل کلاس کنترلر را ارائه نمایید:

                    $url = action('FooController@method');

می توان با فراخوانی و اجرای متد currentRouteAction بر روی Route، به اسم اکشن کنترلر در حال اجرا (صدا زده شده) دسترسی داشته باشید:

                    $action = Route::currentRouteAction();

Controller Middleware

می توان به روش زیر به route های کنترلر، middleware تخصیص داد:

Route::get('profile', [
   'middleware' => 'auth',
   'uses' => 'UserController@showProfile'
]);

با این وجود، تعریف middleware در تابع سازنده ی کنترلر به نسبت روش آسان تری محسوب می شود. با استفاده و فراخوانی متد middleware از تابع سازنده ی کنترلر، می توان به راحتی به کنترلر خود middleware اختصاص دهید. حتی می توانید middleware را به متدهای خاصی از کلاس کنترلر محدود نمایید:

class UserController extends Controller
{
   /**
    * Instantiate a new UserController instance.
    *
    * @return void
    */
   public function __construct()
   {
       $this->middleware('auth');
       $this->middleware('log', ['only' => ['fooAction', 'barAction']]);
       $this->middleware('subscribed', ['except' => ['fooAction', 'barAction']]);
   }
}

ساخت کنترلرهای RESTful

Resource controller ها فرایند ساخت و ایجاد کنترلرهای RESTful را برای resource ها آسان می سازد. به عنوان مثال، می توانید یکcontroller ایجاد کنید که درخواست های HTTP مربوط به عکس های ذخیره شده در اپلیکیشن را مدیریت کند. برای این منظور کافی است دستور آرتیزانmake:controller را فراخوانی کنید:

                    php artisan make:controller PhotoController

دستور یاد شده یک فایل کنترلر در آدرس app/Http/Controllers/PhotoController.php ایجاد می کند. این فایل به ازای هر یک از عملیات قابل اجرای مربوط به resource یک متد در نظر گرفته است.
در گام بعدی می توانید یک route از نوع resourceful ویژه ی کنترلر ثبت و ایجاد نمایید:

                    Route::resource('photo', 'PhotoController');

این تعریف ساده ی route که در نمونه ی فوق مشاهده می شود، در واقع چندین route برای مدیریت مجموعه متفاوتی از action های (عملیات)RESTful بر روی منبع مورد نظر (به عنوان مثال تصاویر) ایجاد می کند. به همین ترتیب، کنترلر ایجاد شده حامل متدهایی برای مدیریت هر یک از اینaction ها می باشد. هر یک از این متدها همراه یادداشت ها و نکاتی می باشند که به شما اطلاع می دهد هر یک وظیفه ی اداره ی کدام URI ها و متدهای درخواست HTTP را بر عهده دارند.
عملیاتی که توسط هر یک از متدهای Resource controller مدیریت و اجرا می شوند:

(اسم روت)Route Name
(عملیات)Action
(مسیر قرار گیری)Path
Verb (متد درخواستHTTP)
photo.index
index
/photo
GET
photo.create
create
/photo/create
GET
photo.store
store
/photo
POST
photo.show
show
/photo/{photo}
GET
photo.edit
edit
/photo/{photo}/edit
GET
photo.update
update
/photo/{photo}
PUT/PATCH
photo.destroy
destroy
/photo/{photo}
DELETE

Partial Resource Routes (تعریف route های منبع به صورت اختصاصی)

به هنگام تعریف یک resource route (یک route برای مسیردهی به منبعی معین همچون عکس ها)، همچنین می توانید یک زیرمجموعه ای ازaction ها و عملیات را برای مدیریت بر روی route مورد نظر مشخص کنید:

Route::resource('photo', 'PhotoController',
               ['only' => ['index', 'show']]);
 
Route::resource('photo', 'PhotoController',
               ['except' => ['create', 'store', 'update', 'destroy']]);

نام گذاری Resource route ها

به صورت پیش فرض تمامی اکشن های مربوط به یک resource controller دارای یک اسم برای route یا مسیرشان هستند (دارای یک route name هستند). در لاراول به شما این امکان داده شده که با ارسال آرایه ی names به عنوان آرگومان به همراه option های خود، این اسم ها را بازنویسی کنید:

Route::resource('photo', 'PhotoController',
               ['names' => ['create' => 'photo.build']]);

ایجاد Resourceهای تودرتو

گاهی لازم است route هایی را برای مسیردهی به یک منبع تودرتو (nested) تعریف کنید. به عنوان مثال یک منبع تصویر ممکن است دارای چندینcomment باشد که به آن تصویر ضمیمه و متصل می باشد. برای تودتو کردن کنترلرهای منبع (ایجاد کنترلرهای منبع تودرتو)، کافی است نشان نقطه را در تعریف route بکار ببرید:

                    Route::resource('photos.comments', 'PhotoCommentController');

این route یک منبع تودرتو ثبت و ایجاد می کند که به وسیله ی URL هایی مانند نمونه ی زیر به راحتی قابل دسترسی است:photos/{photos}/comments/{comments}

<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
class PhotoCommentController extends Controller
{
   /**
    * Show the specified photo comment.
    *
    * @param int $photoId
    * @param int $commentId
    * @return Response
    */
   public function show($photoId, $commentId)
   {
       //
   }
}

افزودن Route های اضافی بر سازمان به کنترلرهای منبع

در صورت نیاز به افزودن route های بیشتر به کنترلر منبع ورای route های پیش فرض، باید پیش از فراخوانی متد Route::resource، نسبت به تعریف آن ها اقدام نمایید. زیرا در غیر این صورت route های تعریف شده توسط متد resource ممکن است به صورت اتفاقی بر route های مکمل شما اولویت پیدا کنند:

Route::get('photos/popular', 'PhotoController@method');
 
Route::resource('photos', 'PhotoController');

کنترلرهای ضمنی (implicit controllers)

لاراول به شما این امکان را می دهد تا یک route برای مدیریت تمامی action های موجود در کلاس کنترلر تعریف کنید. در گام نخست بایستی routeرا با استفاده از متدRoute::controller تعریف نمایید. متد controller دو آرگومان می پذیرد، اولین آرگومان آن URI پایه است که کنترلر مدیریت می کند و اما دومین آرگومان اسم کلاس آن کنترلر می باشد:

                    Route::controller('users', 'UserController');

در مرحله ی بعد متدها را به کنترلر خود اضافه کنید. اسم متد می بایست با متد درخواست HTTP که به آن پاسخ می دهد شروع شود:

<?php
namespace App\Http\Controllers;
class UserController extends Controller
{
   /**
    * Responds to requests to GET /users
    */
   public function getIndex()
   {
       //
   }
 
   /**
    * Responds to requests to GET /users/show/1
    */
   public function getShow($id)
   {
       //
   }
   /**
    * Responds to requests to GET /users/admin-profile
    */
   public function getAdminProfile()
   {
       //
   }
   /**
    * Responds to requests to POST /users/profile
    */
   public function postProfile()
   {
       //
   }
}

همان طور که در مثال بالا مشاهده می کنید، متدهای index به URI ریشه که توسط کنترلر مدیریت می شود، پاسخ می دهد که در این مثال همانusers است.

تخصیص نام به route های کنترلر

در صورت تمایل می توانید برخی از route های موجود در کنترلر را نام گذاری کنید، برای این منظور بازم است آرایه ای از اسم ها را به عنوان آرگومان سوم به متد controller ارسال نمایید:

Dependency injection و کنترلرها

تزریق متد سازنده (Constructor Injection)

Service container (منبع سرویس های فریم ورک لاراول) برای تشخیص تمامی کنترلرهای این چارچوب نرم افزاری بکار می رود. در نتیجه می توانید تمامی dependency های مورد نیاز کنترلر خود را در متد سازنده ی آن اعلان نوع نمایید (type-hint نمایید). dependency ها به صورت خودکار (تشخیص داده) شده و سپس به داخل نمونه ی مورد نظر کنترلر تزریق می شوند (type-hint عبارت است اعلان نوع داده ای مورد انتظار آرگومان در تعریف تابع):

<?php
namespace App\Http\Controllers;
use Illuminate\Routing\Controller;
use App\Repositories\UserRepository;
class UserController extends Controller
{
   /**
    * The user repository instance.
    */
   protected $users;
   /**
    * Create a new controller instance.
    *
    * @param UserRepository $users
    * @return void
    */
   public function __construct(UserRepository $users)
   {
       $this->users = $users;
   }
}

گفتنی است که شما همچنین می توانید تمامی Laravel contract ها را اعلان نوع نمایید. بنابراین اگر container بتواند آن را تشخیص دهد، شما نیز متعاقبا می توانید آن را اعلان نوع (type-hint) نمایید.

تزریق متد

علاوه بر تزریق متد سازنده، شما همچنین می توانید dependency ها را در اکشن متدهای کنترلر خود اعلان نوع (type-hint) نمایید. به عنوان مثال در اینجا، نمونه ی Illuminate\Http\Request را داخل یکی از متدهای خود اعلان نوع می کنیم:

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
class UserController extends Controller
{
   /**
    * Store a new user.
    *
    * @param Request $request
    * @return Response
    */
   public function store(Request $request)
   {
       $name = $request->input('name');
       //
   }
}

اگر متد کنترلر شما همچنین انتظار دریافت ورودی از یک پارامتر route را دارد، کافی است آرگومان های route را بعد از دیگر dependency ها ذکر نمایید. به عنوان مثال اگر route شما به صورت زیر تعریف شده باشد:

                    Route::put('user/{id}', 'UserController@update');

بازهم می توانید Illuminate\Http\Request را اعلان نوع کنید و با تعریف متد کنترلر به صورت زیر، به id که یک route parameter است، دسترسی داشته باشید:

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
class UserController extends Controller
{
   /**
    * Update the specified user.
    *
    * @param Request $request
    * @param int $id
    * @return Response
    */
   public function update(Request $request, $id)
   {
       //
   }
}

قابلیت ذخیره موقت route ها در حافظه ی نهان (Route caching)

توجه:

توجه داشته باشید که Route caching با route هایی که با Closure تعریف شده باشند، سازگاری ندارد. به منظور استفاده از route caching، بایستی تمامی route هایی را که با Closure تعریف شده اند برای استفاده از کلاس های کنترلر تبدیل نمایید.

اگر برنامه ی شما فقط و فقط از route های مبتنی بر کنترلر استفاده می کند، در آن صورت شما می توانید از قابلیت route caching لاراول بهترین استفاده ببرید. استفاده از route cache به طور قابل توجهی مقدار زمان لازم برای ثبت تمامی route های اپلیکیشن را کاهش می دهد. در برخی موارد، ممکن است فرایند ثبت و ایجاد حتی تا 100 برابر سریع تر انجام گیرد. جهت ایجاد یک route cache، می توانید دستور آرتیزانroute:cache را اجرا کنید:

                    php artisan route:cache

اکنون بجای فایل app/Http/routes.php، فایل route های کش شده ی شما مورد استفاده قرار می گیرد. به خاطر داشته باشید که به ازای هرroute جدیدی که اضافه می کنید، بایستی یک route cache جدید نیز ایجاد نمایید. به این خاطر توصیه می کنیم دستور route:cache را حین مستقر سازی و نصب پروژه اجرا نمایید.
به منظور حذف فایل route های کش شده و اجتناب از ایجاد کش جدید، کافی است دستورroute:clear را بکار ببرید:

                    php artisan route:clear
1395/02/22 6858 2415
رمز عبور : tahlildadeh.com یا www.tahlildadeh.com
نظرات شما

نظرات خود را ثبت کنید...