مقدمه
در این مقاله آموزش مفاهیم پایه ای لاراول، میخواهیم با یکی دیگر از مفاهیم laravel یعنی controller ها بیشتر آشنا شویم.
به جای اینکه تمام logic مدیریت درخواست را به عنوان Closure در فایل های route تعریف کنید ، می توانید این رفتار را با استفاده از کلاس های Controller سازماندهی کنید. Controller ها می توانند logic مربوط به request را در یک کلاس واحد گروه بندی کنند. Controller ها در دایرکتوری app/Http/Controllers
ذخیره می شوند.
Controller های اصلی
تعریف Controller ها
در زیر نمونه ای از basic controller class آورده شده است. توجه داشته باشید که کنترلر،base controller class موجود در لاراول را گسترش می دهد. base class چند متد راحت مانند متد middleware
را ارائه می دهد که ممکن است برای پیوستن middleware به controller action استفاده شود:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\User;
class UserController extends Controller
{
/**
* Show the profile for the given user.
*
* @param int $id
* @return View
*/
public function show($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
می توانید روتی را برای این controller action تعریف کنید:
Route::get('user/{id}', '[email protected]');
اکنون ، هنگامی که درخواستی با route URI مشخص مطابقت دارد ، متد show
در کلاس UserController
اجرا می شود. پارامترهای روت نیز به متد ارسال می شوند.
برای گسترش base class بهController ها نیازی نیست.اگرچه ، شما به فیچرهایی مانند middleware
، validate
و متد های dispatch
دسترسی نخواهید داشت.
Controller ها و Namespace ها
توجه به این نکته بسیار مهم است که هنگام controller route نیازی به تعیین full controller namespace نیستیم. از آنجا که RouteServiceProvider
فایل های روت شما را در یک route group که شامل namespace است لود می کند ، ما فقط بخشی از نام کلاس را که بعد از قسمت App\Http\Controllers
از namespace می آید مشخص می کنیم.
اگر می خواهید کنترلرهای خود را بیشتر در دایرکتوری App\Http\Controllers
قرار دهید، از class name خاص نسبت به App\Http\Controllers
root namespace استفاده کنید. بنابراین ، اگر controller class شما App\Http\Controllers\Photos\AdminController
است ، باید روت هایی را به سمت کنترلر رجیسترکنید:
Route::get('foo', 'Photos\[email protected]');
Single Action Controller ها
اگر می خواهید کنترلری تعریف کنید که فقط یک اکشن را کنترل کند ، می توانید یک متد __invoke
روی کنترلر قرار دهید:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\User;
class ShowProfile extends Controller
{
/**
* Show the profile for the given user.
*
* @param int $id
* @return View
*/
public function __invoke($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
هنگام رجیستر روت ها برای action controller ها ، نیازی به تعیین متد ندارید:
Route::get('user/{id}', 'ShowProfile');
شما می توانید با استفاده از آپشن --invokable
از دستور make:controller
یک invokable controlle تولید کنید:
php artisan make:controller ShowProfile --invokable
Controller Middleware
Middleware می تواند به controller's route ها در فایل های route شما اختصاص یابد:
Route::get('profile', '[email protected]')->middleware('auth');
بهتر است که middleware را در سازنده کنترلر خود مشخص کنید. با استفاده از متد middleware
از سازنده کنترلر ، می توانید به راحتی middleware را به controller's action اختصاص دهید. حتی می توانید middleware را فقط به متدهای خاص در کلاس کنترلر محدود کنید:
class UserController extends Controller
{
/**
* Instantiate a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
$this->middleware('log')->only('index');
$this->middleware('subscribed')->except('store');
}
}
همچنین کنترلر به شما امکان می دهند با استفاده از Closure میان افزار یا middlware را رجیستر کنید. این یک روش مناسب برای تعریف middlaware برای یک کنترلر بدون تعریف تمام middleware class فراهم می کند:
$this->middleware(function ($request, $next) {
// ...
return $next($request);
});
شما می توانید middleware را به زیر مجموعه ای از controller action ها اختصاص دهید. با این حال ، ممکن است مشخص شود که کنترلر شما بیش از حد بزرگ شده است. در نظر بگیرید که می توانید کنترلر خود را به چندین کنترلر کوچکتر تبدیل کنید.
Resource Controller ها
روتینگ resource لاراول روتهای "CRUD" را به یک کنترلر با یک خط کد اختصاص می دهد. به عنوان مثال ، ممکن است بخواهید کنترلری ایجاد کنید که کلیه درخواستهای HTTP را برای "عکسهای" ذخیره شده توسط برنامه مدیریت کند. با استفاده از دستور make:controller
Artisan ، می توانیم به سرعت چنین کنترلری ایجاد کنیم:
php artisan make:controller PhotoController --resource
این دستور یک کنترلر در app/Http/Controllers/PhotoController.php
ایجاد می کند. کنترلر شامل متدی برای هر یک از عملیات available resource است.
در مرحله بعدی ، می توانید یک resourceful route به کنترلر رجیسترکنید:
Route::resource('photos', 'PhotoController');
این اعلان single route، روتهای مختلفی را برای مدیریت انواع اکشن رویresource ایجاد می کند. controller تولید شده همواره متدهایی هایی برای هر یک از این اکشن ها دارد ، از جمله یادداشت هایی که شما را از HTTP و URI هایی که آنها مدیریت می کنند ، مطلع می کند.
با ارسال یک آرایه با متد resources
، می توانید بسیاری از resource controller ها را به طور همزمان رجیسترکنید:
Route::resources([
'photos' => 'PhotoController',
'posts' => 'PostController'
]);
Actions Handled با Resource Controller
تعیین Resource Model
اگر از route model binding استفاده می کنید، هنگام تولید کنترلر می توانید از آپشن --model
استفاده کنید:
php artisan make:controller PhotoController --resource --model=Photo
Spoofing از Methods
از آنجا که فرمهای HTML نمی توانند درخواستهای PUT
, PATCH
, یا DELETE
را ایجاد کنند ، برای جعل این افعال HTTP باید یک فیلد hidden _method
اضافه کنید. دستور method
Blade@
می تواند این فیلد را برای شما ایجاد کند:
<form action="/foo/bar" method="POST">
@method('PUT')
</form>
Resource Route های جزئی
هنگام اعلان resource route ، می توانید زیر مجموعه action هایی را که controller باید انجام دهد به جای مجموعه کامل default action ها، مشخص کنید:
Route::resource('photos', 'PhotoController')->only([
'index', 'show'
]);
Route::resource('photos', 'PhotoController')->except([
'create', 'store', 'update', 'destroy'
]);
API Resource Route ها
هنگام اعلان resource route هایی که توسط APIs مصرف می شوند ، معمولاً می خواهید روت هایی را که دارای HTML template هایی مانند اcreate
و edit
هستند را حذف کنید. برای سهولت ، می توانید از متد apiResource
استفاده کنید تا به طور خودکار این دو route را حذف کنید:
Route::apiResource('photos', 'PhotoController');
با ارسال یک آرایه به متد apiResources
، می توانید بسیاری از API resource controller ها را همزمان رجیستر کنید:
Route::apiResources([
'photos' => 'PhotoController',
'posts' => 'PostController'
]);
برای تولید سریع یک API resource controller که شامل متدهای create
یا edit
نباشد، هنگام اجرای دستور make:controller
از سوئیچ api
--
استفاده کنید:
php artisan make:controller API/PhotoController --api
Resource های تودرتو
بعضی اوقات ممکن است لازم باشد route هایی را برای یک resource تو در تو تعریف کنید. به عنوان مثال ، یک photo resource می تواند چندین کامنت داشته باشد که به عکس پیوست شده باشد. برای nest کردن منابع controller ، از علامت "dot" در اعلان route خود استفاده کنید:
Route::resource('photos.comments', 'PhotoCommentController');
این route یک nested resource را رجیستر می کند که می تواند مانند موارد زیر با URIs قابل دسترسی باشد:
/photos/{photo}/comments/{comment}
تو در تو های کم عمق
اغلب داشتن parent و child IDs در یک URI ضروری نیست ، زیرا child ID یک ID یونیک است. هنگام استفاده از unique id مانند کلیدهای اصلی auto-incrementing برای شناسایی مدل های خود در بخش های URI ، می توانید از "shallow nesting" استفاده کنید:
Route::resource('photos.comments', 'CommentController')->shallow();
تعریف روت بالا روتهای زیر را مشخص می کند:
نامگذاری Resource Route ها
به طور پیش فرض ، تمام resource controller action ها یک route name دارند. با این حال ، می توانید با ارسال یک آرایه names
با آپشن های خود ، این نام ها را override کنید:
Route::resource('photos', 'PhotoController')->names([
'create' => 'photos.build'
]);
نامگذاری پارامترهای Resource Route
به طور پیش فرض ، Route::resource
پارامترهای روت را برای روتهای resource شما بر اساس ورژن "singularized" نام resource ایجاد می کند. با استفاده از متد parameters
به راحتی می توانید این را بر اساس هر منبع override بگیرید. آرایه ارسال شده به متد parameters
باید یک آرایه از resource names و parameter names باشد:
Route::resource('users', 'AdminUserController')->parameters([
'users' => 'admin_user'
]);
مثال بالا URI های زیر را برای resource's show
route ایجاد می کند:
/users/{admin_user}
محلی سازی Resource URI ها
به طور پیش فرض، Route::resource
با استفاده از verb های انگلیسی resource URI ایجاد می کند. اگر می خواهید create
و edit
را لوکال کنید، می توانید از متد Route::resourceVerbs
استفاده کنید که می تواند در متد boot
از AppServiceProvider
انجام شود:
use Illuminate\Support\Facades\Route;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Route::resourceVerbs([
'create' => 'crear',
'edit' => 'editar',
]);
}
پس از سفارشی سازی verb ها،resource route registration هایی مانند Route::resource('fotos', 'PhotoController')
URI های زیر را تولید می کند:
/fotos/crear
/fotos/{foto}/editar
ادامه دارد...
نظرات کاربران (0 نظر)