نسخه:

کنترل کننده ها

معرفی

به جای اینکه تمام منطق رسیدگی به درخواست خود را به عنوان Closures در فایل های مسیر تعریف کنید، ممکن است بخواهید این رفتار را با استفاده از کلاس های Controller سازماندهی کنید. کنترلرها می توانند منطق رسیدگی به درخواست مرتبط را در یک کلاس واحد گروه بندی کنند. کنترلرها در app/Http/Controllers دایرکتوری ذخیره می شوند.

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

تعریف کنترلرها

در زیر نمونه ای از یک کلاس کنترل کننده پایه آورده شده است. توجه داشته باشید که کنترل کننده کلاس کنترل کننده پایه موجود در لاراول را گسترش می دهد. کلاس پایه چند روش آسان مانند middleware متد را ارائه می دهد که ممکن است برای اتصال میان افزار به اقدامات کنترل کننده استفاده شود:

<?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)]);
}
}

شما می توانید مسیری را برای این عملکرد کنترلر تعریف کنید:

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

اکنون، زمانی که یک درخواست با URI مسیر مشخص شده مطابقت داشته باشد، show متد روی UserController کلاس اجرا خواهد شد. پارامترهای مسیر نیز به متد ارسال خواهند شد.

کنترلرها نیازی به گسترش کلاس پایه ندارند . با این حال، به ویژگی‌های راحتی مانند، و روش‌ها دسترسی middleware نخواهید validate داشت dispatch .

کنترلرها و فضاهای نام

توجه به این نکته بسیار مهم است که هنگام تعریف مسیر کنترلر، نیازی به تعیین فضای نام کامل کنترلر نداشتیم. از آنجایی که RouteServiceProvider فایل‌های مسیر شما را در یک گروه مسیر که حاوی فضای نام است بارگیری می‌کند، ما فقط بخشی از نام کلاس را که بعد از App\Http\Controllers بخشی از فضای نام قرار می‌گیرد، مشخص کردیم.

اگر می‌خواهید کنترل‌کننده‌های خود را عمیق‌تر در App\Http\Controllers دایرکتوری قرار دهید، از نام کلاس خاص نسبت به App\Http\Controllers فضای نام ریشه استفاده کنید. بنابراین، اگر کلاس کنترلر کامل شما App\Http\Controllers\Photos\AdminController , باید مسیرهایی را به کنترلر مانند زیر ثبت کنید:

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

کنترلرهای تک اقدام

اگر می‌خواهید کنترل‌کننده‌ای تعریف کنید که فقط یک عمل را انجام دهد، می‌توانید یک __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)]);
}
}

هنگام ثبت مسیرها برای کنترلرهای تکی، نیازی به تعیین روش ندارید:

Route::get('user/{id}', 'ShowProfile');

--invokable شما می توانید با استفاده از دستور Artisan یک کنترل کننده فراخوانی ایجاد کنید make:controller :

php artisan make:controller ShowProfile --invokable

میان افزار کنترلر

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

Route::get('profile', 'UserController@show')->middleware('auth');

با این حال، تعیین میان افزار در سازنده کنترلر راحت تر است. با استفاده 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 ثبت کنید. این یک راه راحت برای تعریف یک میان افزار برای یک کنترل کننده بدون تعریف کل کلاس میان افزار فراهم می کند:

$this->middleware(function ($request, $next) {
// ...
 
return $next($request);
});

می‌توانید میان‌افزار را به زیرمجموعه‌ای از اقدامات کنترل‌کننده اختصاص دهید. با این حال، ممکن است نشان دهنده بزرگ شدن کنترلر شما باشد. در عوض، کنترل کننده خود را به چندین کنترلر کوچکتر تقسیم کنید.

کنترل کننده های منابع

مسیریابی منابع لاراول مسیرهای معمولی "CRUD" را به یک کنترلر با یک خط کد اختصاص می دهد. برای مثال، ممکن است بخواهید یک کنترل‌کننده ایجاد کنید که تمام درخواست‌های HTTP برای "عکس‌های" ذخیره شده توسط برنامه شما را مدیریت کند. با استفاده از make:controller دستور Artisan، می توانیم به سرعت چنین کنترل کننده ای ایجاد کنیم:

php artisan make:controller PhotoController --resource

این دستور یک کنترلر در app/Http/Controllers/PhotoController.php . کنترل کننده شامل یک روش برای هر یک از عملیات منابع موجود خواهد بود.

در مرحله بعد، می توانید یک مسیر پرمحتوا به کنترل کننده ثبت کنید:

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

این اعلان مسیر واحد، مسیرهای متعددی را برای انجام انواع اقدامات روی منبع ایجاد می کند. کنترل‌کننده ایجاد شده قبلاً روش‌هایی را برای هر یک از این اقدامات، از جمله یادداشت‌هایی که به شما از افعال HTTP و URI‌هایی که مدیریت می‌کنند، آگاه می‌کند، خواهد داشت.

شما می توانید با ارسال یک آرایه به resources متد، بسیاری از کنترل کننده های منبع را به طور همزمان ثبت کنید:

Route::resources([
'photos' => 'PhotoController',
'posts' => 'PostController',
]);

اقدامات انجام شده توسط کنترل کننده منابع

فعل URI عمل نام مسیر
گرفتن /photos فهرست مطالب photos.index
گرفتن /photos/create ايجاد كردن عکس. ایجاد
پست /photos فروشگاه photos.store
گرفتن /photos/{photo} نشان می دهد عکس.نمایش
گرفتن /photos/{photo}/edit ویرایش کنید photos.edit
PUT/PATCH /photos/{photo} به روز رسانی photos.update
حذف /photos/{photo} از بین رفتن عکس. تخریب

مشخص کردن مدل منبع

اگر از اتصال مدل مسیر استفاده می‌کنید و می‌خواهید که روش‌های کنترل‌کننده منبع، نمونه‌ای از مدل را تایپ کنند، می‌توانید --model هنگام تولید کنترل‌کننده از این گزینه استفاده کنید:

php artisan make:controller PhotoController --resource --model=Photo

روش های فرم جعل

از آنجایی که فرم‌های HTML نمی‌توانند، یا درخواست ایجاد PUT کنند PATCH ، DELETE باید یک _method فیلد مخفی برای جعل این افعال HTTP اضافه کنید. دستورالعمل @method Blade می تواند این فیلد را برای شما ایجاد کند:

<form action="/foo/bar" method="POST">
@method('PUT')
</form>

مسیرهای منابع جزئی

هنگام اعلام مسیر منبع، می‌توانید زیرمجموعه‌ای از اقداماتی را که کنترلر باید انجام دهد، به جای مجموعه کامل اقدامات پیش‌فرض مشخص کنید:

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

مسیرهای منبع API

هنگام اعلام مسیرهای منبعی که توسط APIها مصرف می شوند، معمولاً می خواهید مسیرهایی را که الگوهای HTML را ارائه می دهند حذف create کنید edit . برای راحتی، می توانید از apiResource روشی برای حذف خودکار این دو مسیر استفاده کنید:

Route::apiResource('photos', 'PhotoController');

شما می توانید با ارسال یک آرایه به متد، بسیاری از کنترل کننده های منبع API را به طور همزمان ثبت کنید apiResources :

Route::apiResources([
'photos' => 'PhotoController',
'posts' => 'PostController',
]);

create برای تولید سریع یک کنترل‌کننده منبع API که شامل یا edit متدها نمی‌شود ، --api هنگام اجرای make:controller دستور از سوئیچ استفاده کنید:

php artisan make:controller API/PhotoController --api

منابع تو در تو

گاهی اوقات ممکن است لازم باشد مسیرهایی را برای یک منبع تودرتو تعریف کنید. به عنوان مثال، یک منبع عکس ممکن است چندین نظر داشته باشد که ممکن است به عکس پیوست شود. برای قرار دادن کنترل‌کننده‌های منبع، از علامت نقطه در اعلان مسیر خود استفاده کنید:

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

این مسیر یک منبع تودرتو را ثبت می کند که ممکن است با URI هایی مانند زیر قابل دسترسی باشد:

/photos/{photo}/comments/{comment}

لانه سازی کم عمق

اغلب، داشتن شناسه والد و فرزند در یک URI کاملاً ضروری نیست، زیرا شناسه فرزند در حال حاضر یک شناسه منحصر به فرد است. هنگام استفاده از شناسه منحصربه‌فرد مانند کلیدهای اصلی افزایش خودکار برای شناسایی مدل‌های خود در بخش‌های URI، می‌توانید از «تودرتوی سطحی» استفاده کنید:

Route::resource('photos.comments', 'CommentController')->shallow();

تعریف مسیر بالا مسیرهای زیر را تعریف می کند:

فعل URI عمل نام مسیر
گرفتن /photos/{photo}/comments فهرست مطالب photos.comments.index
گرفتن /photos/{photo}/comments/create ايجاد كردن عکس.نظرات.ایجاد
پست /photos/{photo}/comments فروشگاه photos.comments.store
گرفتن /comments/{comment} نشان می دهد نظرات.نمایش
گرفتن /comments/{comment}/edit ویرایش کنید نظرات.ویرایش
PUT/PATCH /comments/{comment} به روز رسانی نظرات.به روز رسانی
حذف /comments/{comment} از بین رفتن نظرات.ویران کردن

نامگذاری مسیرهای منابع

به طور پیش فرض، تمام اقدامات کنترل کننده منبع یک نام مسیر دارند. با این حال، می توانید این نام ها را با ارسال یک names آرایه با گزینه های خود لغو کنید:

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

نامگذاری پارامترهای مسیر منبع

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

Route::resource('users', 'AdminUserController')->parameters([
'users' => 'admin_user'
]);

مثال بالا URI های زیر را برای مسیر منبع تولید می کند show :

/users/{admin_user}

مسیرهای منابع محدوده

گاهی اوقات، هنگامی که به طور ضمنی چندین مدل Eloquent را در تعاریف مسیر منابع متصل می‌کنید، ممکن است بخواهید دامنه مدل Eloquent دوم را به گونه‌ای تنظیم کنید که باید فرزند اولین مدل Eloquent باشد. به عنوان مثال، این وضعیت را در نظر بگیرید که یک پست وبلاگ را توسط یک کاربر خاص بازیابی می کند:

use App\Http\Controllers\PostsController;
 
Route::resource('users.posts', PostsController::class)->scoped();

می‌توانید با ارسال یک آرایه به scoped روش، کلیدهای مسیر پیش‌فرض مدل را لغو کنید:

use App\Http\Controllers\PostsController;
 
Route::resource('users.posts', PostsController::class)->scoped([
'post' => 'slug',
]);

هنگام استفاده از یک اتصال ضمنی با کلید سفارشی به عنوان پارامتر مسیر تودرتو، لاراول به طور خودکار محدوده پرس و جو را برای بازیابی مدل تودرتو توسط والد خود با استفاده از قراردادها برای حدس زدن نام رابطه روی والد، بررسی می کند. در این حالت، فرض می شود که User مدل دارای رابطه ای به نام posts (جمع نام پارامتر مسیر) است که می تواند برای بازیابی Post مدل استفاده شود.

بومی سازی URI های منبع

به طور پیش فرض، Route::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',
]);
}

هنگامی که افعال سفارشی شدند، یک ثبت مسیر منبع مانند Route::resource('fotos', 'PhotoController') URI های زیر را تولید می کند:

/fotos/crear
 
/fotos/{foto}/editar

تکمیل کنترل کننده های منابع

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

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

به یاد داشته باشید که کنترلرهای خود را متمرکز نگه دارید. اگر متوجه شدید که به طور معمول به روش‌هایی خارج از مجموعه اقدامات معمول منابع نیاز دارید، کنترل کننده خود را به دو کنترلر کوچکتر تقسیم کنید.

تزریق وابستگی و کنترلرها

تزریق سازنده

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

<?php
 
namespace App\Http\Controllers;
 
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;
}
}

همچنین می توانید هر قرارداد لاراول را تایپ کنید . اگر ظرف می تواند آن را حل کند، می توانید آن را تایپ کنید. بسته به برنامه شما، تزریق وابستگی های شما به کنترلر ممکن است تست پذیری بهتری را ارائه دهد.

روش تزریق

علاوه بر تزریق سازنده، می‌توانید وابستگی‌های متدهای کنترلر خود را نیز تایپ کنید. یک مورد رایج برای تزریق روش، تزریق Illuminate\Http\Request نمونه به روش‌های کنترل‌کننده است:

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

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

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

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

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

حافظه پنهان مسیر

مسیرهای مبتنی بر بسته شدن را نمی توان در حافظه پنهان ذخیره کرد. برای استفاده از کش مسیر، باید هر مسیر Closure را به کلاس های کنترلر تبدیل کنید.

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

php artisan route:cache

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

می توانید از route:clear دستور برای پاک کردن کش مسیر استفاده کنید:

php artisan route:clear