مفاهیم پایه کنترلرها در فریم ورک لاراول
تعریف کنترلر لاراول
کنترلر در لاراول با استفاده از composer به صورت ذیل تعریف می شود که ShowProfile نام کنترلر ما می باشد
php artisan make:controller ShowProfile
در زیر مثالی از کلاس کنترل کننده اصلی آورده شده است. توجه داشته باشید که کنترلر مربوطه از کنترلر اصلی مشتق شده است. کلاس پایه ای که کلاس های خود را در لاراول از آن مشتق می گیرید برای استفاده راحتر از middleware ها در کلاس پایه متدهایی پیش بینی شده است تا به راحتی بتوانید از میدل ویرها در داخل کنترلر خود در یکی از اکشن های موجود یا سازنده کلاس استفاده کنید.
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\User;
class UserController extends Controller
{
public function show($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
شما می توانید برای دسترسی به اکشن show در مثال بالا یک مسیر به صورت ذیل در فایل web.php قرار دهید.
Route::get('user/{id}', 'UserController@show');
با مراجعه با این آدرس، متد show در کنترلز user اجرا می شود و پارامتر id در این متد گرفته می شود.
نکته : الزاما نیاز نیست شما در ساخت کلاس هایتان از کنترلر پایه لاراول، کلاس خود را مشتق کنید اما اگر اینکار را انجام ندهید برخی امکانات از جمله استفاده از middleware ، validate و ... را نخواهید داشت.
Controllers & Namespaces فضای نام در کنترلر ها
این نکته خیلی مهم است که شما نیازی به تعیین آدرس کنترلر خود در routing (مسیر دهی) ندارید RouteServiceProvider پرونده های شما را گروه بندی کرده و فضای نام (namespace) مسیرهای مختلف را در اجرای برنامه آماده کرده است و ما فقط بخشی از مسیر دسترسی به کنترلر خود را وارد میکنیم و نیازی به وارد کردن App\Http\Controllers در ابتدای مسیرها نداریم
همچنین می توانیم کنترلر های خود را در پوشه هایی در مسیر App\Http\Controllers قرار دهیم تا گروه بندی کنترلر های خود را داشته باشیم مثلا کنترلرهای بخش ادمین در پوشه ای با نام admin در مسیر یاد شده ایجاد می کنیم و کنترلر های این بخش را در آن قرار می دهیم شما می توانید به دلخواه خود در مسیر یاده شده پوشه های تو در تو یا کنار هم ایجاد کنید. مثلا اگر کنترلر ما با نام AdminController در مسیر App\Http\Controllers\Photos\AdminController باشد نحوه مسیردهی در فایل web.php به صورت ذیل خواهد بود
Route::get('foo', 'Photos\AdminController@method');
Single Action Controllers
single action controllers به معنای انجام فقط یک عمل در یک کنترلر می باشد اگر می خواهید یک کنترلر را تعریف کنید که فقط یک اکشن داشته باشد ، می توانید از متد invoke در بدنه کنترلر استفاده کنید:
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\User;
class ShowProfile extends Controller
{
public function __invoke($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
برای مسیردهی این متد در کنترلر مربوطه شما نیازی ندارید اسم متد را در مسیر خود عنوان کنید و فقط نام کنترلر کافیست
Route::get('user/{id}', 'ShowProfile');
برای ساخت یک کنترلر invokable (فقط یک متد قابل پذیرش) از دستور ساخت یک کنترلر بعلاونه کلمه invokable استفاده کنید
php artisan make:controller ShowProfile --invokable
Controller Middleware ( استفاده از middleware در کنترلرها )
همانطور در مبحث middleware گفتیم که میدل ویر ها را می توان بر روی مسیر مورد اختصاص داد
Route::get('profile', 'UserController@show')->middleware('auth');
اما گاهی مورد نیاز که middleware های خود را در داخل کنترلر اختصاص دهید این کار به راحتی انجام می شود اما شما باید middleware را داخل سازنده کلاس خود استفاده کنید.
class UserController extends Controller
{
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);
});
آموزش لاراول (laravel) دوره جامع پروژه محور ساخت فروشگاه اینترنتی
Resource Controllers
کنترلرهای resource به شما این امکان را می دهند که با یک خط کد مسیر تمام متدهای موجود در کنترلر از نوع resource را ایجاد کنید. فرض کنید شما یک کنترلر دارید برای مدیرت تصاویر پس درخواستهای HTTP برای این کنترلر را در نظر بگیرید متدهای مختلف get ، post ، delete و ... را دریافت خواهید کرد reource controllers این عملیات مسیر دهی و ایجاد متدهای مختلف را به صورت اتوماتیک برای شما انجام می دهد. برای ساخت کنترلر از نوع resource باید در هنگام ساخت کنترلر از کلمه resource استفاده کنید.
php artisan make:controller PhotoController --resource
با اجرای این دستور یک کنترلر به نام PhotoController در مسیر app/Http/Controllers/PhotoController.php ساخته می شود کنترلر ساخته شده شامل متدهای مورد نیاز خواهد بود. برای مسیردهی یک کنترلر resource در فایل web.php یا api.php به صورت ذیل عمل می کنیم این مسیر به تمام متدهای موجود در کنترلر که در ساخت کنترلر در آن موجود بود ایجاد دسترسی خواهد کرد.
Route::resource('photos', 'PhotoController');
شما می توانید از یک مسیردهی Resource برای ایجاد دسترسی برای چندین کنترلر استفاده کنید
Route::resources([
'photos' => 'PhotoController',
'posts' => 'PostController'
]);
متدها و مسیرهای دسترسی در resource controller
Route Name | Action | URI | Verb |
GET | /photos | index | photos.index |
GET | /photos/create | create | photos.create |
POST | /photos | store | photos.store |
GET | /photos/{photo} | show | photos.show |
GET | /photos/{photo}/edit | edit | photos.edit |
PUT/PATCH | /photos/{photo} | update | photos.update |
DELETE | /photos/{photo} | destroy | photos.destroy |
Specifying The Resource Model
مشخص کردن یک مدل منبع برای کنترلر نیز امکان پذیر است اگر از مسیر دهی model binding استفاده می کنید کافیست درهنگام تعریف resource controller نام مدل خود را نیز به دستور اضافه کنید
php artisan make:controller PhotoController --resource --model=Photo
Spoofing Form Methods
در html ما نوع متدهای delete , put , patch نداریم ولی می توانیم این متدها را جعل کنیم برای اینکار کافیست در blade خود داخل فرم از کلمه method و نوع متد خود را عنوان کنیم
@method('PUT')
Partial Resource Routes (مسیر فقط برای متدهای انتخابی در resource)
هنگام تعریف مسیر برای یک کنترلر Resource شما می توانید مسیر را برای تعداد از متدها درست کنید و از دسترسی کاربر به تمام متدها جلوگیر کنید به مثال های ذیل توجه کنید.
Route::resource('photos', 'PhotoController')->only([
'index', 'show'
]);
Route::resource('photos', 'PhotoController')->except([
'create', 'store', 'update', 'destroy'
]);
API Resource Routes
API Resource Routes به شما کمک می کند تا به راحتی برنامه هایی که از api شما استفاده می کنند محدودیت هایی داشته باشند این محدودیت ها عملیات ثبت و ویرایش در resource controller ها را برای برنامه های خارج از هسته لاراول، محدود می کند برای استفاده از این ویژگی مسیر دسترسی به resource controller خود را با apiResource مشخص کنید.
Route::apiResource('photos', 'PhotoController');
شما می توانید از یک مسیردهی apiResource برای ایجاد دسترسی برای چندین کنترلر resource استفاده کنید
Route::apiResources([
'photos' => 'PhotoController',
'posts' => 'PostController'
]);
برای ساخت یک API resource controller که متدهای edit و create را نداشته باشد در هنگام تعریف کنترلر خود از کلمه api در آخر دستور خود استفاده کنید
php artisan make:controller API/PhotoController --api
Naming Resource Routes
به صورت پیش فرض resource routes تعریف شده دارای یک route name می باشد اما گاهی اوقات شاید نیاز به تغییر این route name باشد برای تغییر نام مسیرهای مورد نظر خود از کلمه names استفاده کنید که می تواند آرایه ای از نام های انتسابی را دریافت کند.
Route::resource('photos', 'PhotoController')->names([
'create' => 'photos.build'
]);
نام گذاری پارامترهای Resource Route
به طور پیش فرض Route::resource به صورت singularized تمام دسترسی های لازم به کنترلر ما را ایجاد می کنند این دسترسی ها شامل پارامترهای مسیرها نیز می باشد شما می توانید نام پارامتر مورد نظر خود را با کلمه parameters تغییر دهید. برای این کار پارمتر یا پارامترهای خود را به صورت آرایه ای برای آن ارسال کنید.
Route::resource('users', 'AdminUserController')->parameters([
'users' => 'admin_user'
]);
مثال بالا آدرس (url) ذیل را برای متد show تولید می کند
/users/{admin_user}
Localizing Resource URIs
بومی سازی یا تغییر نام مسیرها در Resource Route امکان پذیر می باشد البته این تغییرات به صورت کلی روی تمام مسیرهای Resource Route اعمال خواهد شد به صورت پیش فرض Route::resource آدرس (url) هایی با افعال انگلیسی تولید می کند اگر شما بخواهید نام هرکدام از این مسیرها مثل Create و Edit را تغییر دهید باید از متد Route::resourceVerbs استفاده کنید برای اینکار در متد boot فایل AppServiceProvider از متد resourceVerbs استفاده کنید
use Illuminate\Support\Facades\Route;
public function boot()
{
Route::resourceVerbs([
'create' => 'crear',
'edit' => 'editar',
]);
}
پس از تعریف دوباره نام مسیرها به زبان محلی مورد نظر، مسیرهای ذیل برای کنترلر PhotoController ایجاد خواهد (PhotoController مثال می باشد و برای مسیر دسترسی به هر کنترلری این مسیرها به زبان محلی تغییر خواهد کرد)
/fotos/crear
/fotos/{foto}/editar
Supplementing Resource Controllers
افزودن یک متد جدید به Resource Controller ها گاهی اوقات نیاز می باشد پس برای متد جدید کنترلر خود باید مسیر آن را نیز تعیین کنید که حتما باید قبل از مسیر Route::resource کنترلر مورد نظر باشد برای مثال شاید شما در کنترلر PhotoController یک متد (تابع) با نام popular تعریف کنید پس به سورت ذیل مسیرهای خود را انجام داده باشید تا به ین متد دسترسی داشته باشید
Route::get('photos/popular', 'PhotoController@popular');
Route::resource('photos', 'PhotoController');
تزریق وابستگیها در کنترلرها
تزریق وابستگی در سازنده کلاس Constructor Injection
لاراول با استفاده از service container امکان تزریق وابستگی را به متدهای یک کلاس را مهیا می کند و فقط نیاز دارید که اسم کلاس خود را در بخش ورودی سازنده کلاس خود تعریف کنید لاراول تمام عملیات تزریق وابستگی را انجام می دهد به مثال ذیل توجه کنید که عملیات ساختن یک کلاس جدید از کلاس UserRepository با تزریق وابستگی به راحتی انجام می شود.
namespace App\Http\Controllers;
use App\Repositories\UserRepository;
class UserController extends Controller
{
protected $users;
public function __construct(UserRepository $users)
{
$this->users = $users;
}
}
تزریق وابستگی در متدهای یک کنترلر Method Injection
علاوه بر تزریق وابستگی در سازنده کلاس، شما می توانید تزریق وابستگی در تمام متدهای دیگر یک کنترلر را داشته باشید که معروفترین روش تزریق همان Request $request می باشد که عموما در متدهای خود تا به حال استفاده کرده اید
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function store(Request $request)
{
$name = $request->name;
//
}
}
حال سوالی برای همه پیش می آید که شاید متد (تابع) مورد نظر ما در کنترلر موجود دارای پارامتر ورودی باشد! اصلا جای نگرانی نیست شما می توانید تزریق وابستگی خود را انجام دهید تعداد تزریق وابستگی در لاراول به دلخواه خود شما می باشد به مثال ذیل توجه کنید
Route::put('user/{id}', 'UserController@update');
این متد در کنترلر می تواند هم id را بگیرد و هم تزریق های وابستگی دیگر را که در مثال ذیل کاملا مشهود می باشد
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function update(Request $request, $id)
{
//
}
}
Route Caching
اگر در پروژه خود فقط از مسیرهای ختم شده به کنترلرها استفاده می کنید می توانید کش مسیر در لاراول استفاده کنید این فایل کش مسیرها می توانید سرعت درخواست های شما را تا 100 برابر بیشتر کند برای استفاده از Route caching لاراول کافیست دستور ذیل را در کنسول خود اجرا کنید
php artisan route:cache
بعد از اجرای این دستور فایل کش route دوباره بازسای می شود به یاد داشته باشید که برای افزودن مسیرهای جدید که در فایل های Web.php یا api.php تعریف کرده اید باید دوباره دستور بالا را اجرا کنید تا مسیر جدید شناخته شود و برای حذف کردن کش route می توانید از دستور ذیل استفاده کنید
php artisan route:clear
نکته : کسانی که از هاست های اشتراکی برای میزبانی پروژه لاراول خود استفاده می کنند و دسترسی به اجرای دستورات composer ندارند می توانند برای حذف route cache فایل bootstrap/cache/routes.php را حذف کنند