تعداد بازدید: 1900

Controller and View

رابط میان view و model را controller می نامیم که وظیفه دریافت اطلاعات بوسیله model از پایگاه داده و آماده سازی آن ها و ارسال به view را داراست. کنترلر همان رابط میان درخواست و پاسخ می باشد(ماژولی که به صورت مستقیم با درخواست ها و پاسخ ها در ارتباط است).

ساخت controller  با artisan :

php artisan make:controller ProductController

نکته : ما به ازای هر ماژول یا هر موجودیت به migration , model , controller نیاز داریم که با یک فرمان می توان همه آن ها را ساخت.

به خاطر این که controller را مرکز پردازش داده ها می نامیم در نتیجه ماژول های مختلفی نیاز هست تا در اون import بشه مثلا model مربوطه اون.

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests\storeProduct;
use App\product;

class ProductController extends Controller
{

    public function index(){}
    public function show($id){}
    public function create(){}
    public function store(StoreBook $request,BookAction $action){}
    public function edit(int $id){}
    public function update(UpdateBook $request,int $id, BookAction $action){}
    public function delete(int $id){}
    
}

Controllers & Namespaces

مثلا در کد بالا :

  • import کردن App\product برای استفاده از مدل product .
  • import کردن App\Http\Requests\storeProduct برای استفاده از شئ request ساخته شده توسط کاربر و validate کردن ورودی های کاربر.
  • import کردن Illuminate\Http\Request برای استفاده از شئ request پیش فرض ساخته شده در لاراول. همان طور که گفتیم درخواست ها مستقیما به کنترلر می روند پس این شئ Request در کنترلر جاری است.

ما در اصطلاح می گیم import کردن . خوب این کار رو با استفاده از namespace انجام میدیم دقیق تر باید بگوییم نشانی دادن. یعنی به فایل کلاس مربوطه می ریم و نام کلاس رو به انتهای namesspace اون اضافه می کنیم و در کنترولر خودمون use می کنیم. مثلا در کلاس مدل product و با namespace برابر با App میشه use App\product که به معنی این هست که از product با همین شکل می تونید استفاده کنید.

لاراول از الگوریتم نام دهی psr-4 استفاده می کند.پس باید کلاس ها هم نام با فایل ها باشد و مسیر فایل namespace معرفی گردد.

برای مرتب شدن کدهای موجود در کنترلر اصلی resource ما باید تنها باید متد های مربوط به عملیات های اصلی CRUD را در خود داشته باشد. سایر منطق های کنترلر را در کلاس های مجزا در پوشه کنترلر ایجاد می کنیم. مثلا اگر عملگری جهت افزودن محصول به سبد خرید در وب سایت نیاز داشته باشیم یک کلاس مجزا برای آن با نام AddToCart می سازیم.

دسته بندی Controller

بر اساس نوع درخواست می توان چندین نوع Controller داشت . مثلا یکی برای api و یکی برای web و همچنین آن ها را به RouteServiceProvider معرفی کرد. مثلا درخواستی که برای api می آید توسط Controller از نوع api پشتیبانی گردد و همچنین درخواست هایی که از سمت web می آید به کنترلر web می رود.

همه کنترلر ها در مسیر app\Http\Controllers میسازیم. در پوشه ای مجزا کنترلر های مربوط به Api قرار می دهیم. برای ساخت آن هم می توان فرمان زیر را اجرا کرد :

php artisan make:controller Api/ProductController

پس از اجرای فرمان بالا کنترلر با namespace App\Http\Controllers\Api; ساخته می شود.تنها تفاوت در api و web نحوه athenticate و نگهداری session در آنها میباشد.

قرار دادن کنترلر های مربوط به Api در پوشه جدا کاملا اختیاری است و حتی ممکن است ما کنترل های مربوط به ادمین یا سایر موارد راهم دسته بندی کنیم. برای سهولت کار و شلوغ نشدن پوشه کنترلر می باشد . دقت داشته باشید در زمان پوشه بندی کنترلر ها از الگوریتم psr-4 پیروی کنید و همچنین اگر به صورت دستی کنترلر می سازید (بدون استفاده از artisan) dump-autoload را فراموش نکنید.

مثلا یک کنترلر با نام MovieController برای یک مدل با نام Movie داریم که در درون کنترلر ما متد های SearchMovie یا LoadMovieImages و UploadMovieImages و … دارد. می توان هر یک از منطق ها را در یک کنترلر مجزا گذاشت و در همین راستا ما به اصل SRP (Single Responsibility Principle) عمل کرده ایم.

می توان کلاس هایی مجزا با نام های SearchMovieController, LoadMovieImagesController, UploadMovieImagesController ساخت و اگر لازم به استفاده از Single Action Controllers بود از متد __invoke استفاده کرد:

//old
#Route::post('searchMovie', 'MovieController@searchMovie');
#Route::get('loadMoviesImages', 'MovieController@loadMovieImages');
//new
Route::post('searchMovie', 'SearchMovieController');
Route::get('loadMoviesImages', 'LoadMovieImagesController');

مثلا کنترلر SearchMovieController به شکل زیر خدمات می دهد :

namespace App\Http\Controllers;
use Illuminate\Http\Request;
class SearchMovieController extends Controller
{
    public function __invoke(){}
}

بحث دیگر در اینجا  logic مشترک در کنترلر های api و web میباشد که ما این مشکل را با نوشتن کد های مشترک در فایل جدا گانه و فراخوانی آنها در کنترلر ها حل میکنیم.

Resource Controllers

resource ها مفعول های عملیات های CRUD می باشند. هر کنترلر یک سری متد برای هر resource دارد. به ازای resource برابر با photo متدها و route ها با هم رابطه زیر را دارند:

Verb URI Action Route Name
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

در زمان ایجاد route هم می توان کد زیر را برای ارتباط میان resource و controller و route برقرار کرد:

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

در زمان ساخت کنترلر هم می توان با آپشن --resource یک کنترلر با متد های پیش فرض ساخت :

php artisan make:controller PhotoController --resource

Dependency Injection & Controllers

هر کنترلر در زمان ایجاد (Constructor Injection) و یا استفاده متد (Method Injection) آن می تواند یک سرویس را برای خود فراهم کند (سرویس می تواند یک شئ از یک کلاس باشد). این کار توسط service container انجام می شود. service container تمامی کنترلر ها را در هم می آمیزد و این کار باعث می شود که شما در متد های خود بتوانید از اشیاء دیگر کلاس ها استفاده کنید.

نمایش view در controller

تابعی داریم که view را در controller ما render می کند. این تابع دو پارامتر می گیرد.

<?php view(PATH, PARAMS) ?>
  • PATH : مسیر فایل view .view ها در لاراول در مسیر resources/views قرار دارند و آدرس دهی برای نام فایل view در این تابع از ریشه مسیر گفته شده است.
  • PARAMS : برای ارسال پارامتر به view از تابع compact استفاده می کنیم .
<?php
public function newProduct()
{
    $title = "Add New Product";
    return view('new-product',compact('title'));
}

در مثال بالا فایل resourses/views/new-product.blade.php که پارامتر title با مقدار خاص به آن ارسال شده فراخوانی می شود. نحوه مسیر دهی در تابع view با . می باشد مثلا اگر فایلی در مسیر product/single.blade.php باشد به شکل product.single آدرس دهی می گردد.

اشتراک گذاری :

مدیر وب سایت گنوتک . برنامه نویسی رو با زبان C در هفده سالگی شروع کردم . در حال حاضر به برنامه نویسی php برپایه معماری MVC , HMVC و همچنین سیستم مدیریت محتوای WordPress و فریم ورک محبوب لاراول علاقه مند هستم و دوست دارم اطلاعاتم رو با شما به اشتراک بگذارم.

2 دیدگاه برای Controller and View

  1. سلام خسته نباشید میخواستم بدونم میشه یک route داست و این route رو به چنتا کنترلر وصل کرد که همشون اطلاعاتشون بیاد تو یک view?

    • این کار از نظر ساختاری اشتباه است . اگر نمی خواهید چندین روت تعریف کنید حتما با ارسال پارامتر همراه با روت مدیریت کنترلر ها انجام بدهید. در داخل همان کنترلر می توان یک روت جدید تعریف کرد و درخواست را به وجوه مختلف مدیریت کرد.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *