فهرست:

ساده ترین حالت Route

ابتدایی ترین Route ها در لاراول شامل یک URI و یک Closure می باشند به مثال زیر دقت کنید.

Route::get('foo', function () {
    return 'Hello World';
});

Route ها کجا هستند

تمام Route های لاراول در فولدر routes در پروژه شما تعریف شده اند. این فایل ها به طور خودکار توسط فریم ورک Laravel بارگذاری می شوند. فایل routes/web.php مسیرهایی را برای رابط وب شما تعریف می کند. در روت های فایل web.php به صورت خودکار، میدلورهای session و csrf اعمال می شوند. این میدلورها در لاراول، در روت های فایل api.php اعمال نمی شوند، به خاطر اینکه روت api ها در این فایل مشخص می شوند و درخواست هایی که با api ها انجام می شوند، نیازی به این میدلورها ندارند. در عمده برنامه های نوشته شده توسط لاراول، تعیین روت های از فایل routes/web.php شروع خواهید شد. با وارد کردن URL در آدرس بار مرورگر، می توان به روت های تعریف شده در route/web.php دسترسی پیدا کرد. به عنوان مثال، با رفتن به آدرس http://your-app.test/user در مرورگر خود ، می توانید به Route زیر دسترسی کنید.

routes/web.php
use App\Http\Controllers\UserController;

Route::get('/user', [UserController::class, 'index']);

روت هایی که در فایل route/api.php تعریف می شوند در یک گروه تو در تو داخل RouteServiceProvider قرار می گیرند. در این گروه، آدرس هایی با پیشوند /api به طور خودکار ایجاد خواهند شد و نیازی نیست این آدرس ها بصورت دستی در فایل تعریف شوند می شود، شما با تغییر کلاس در RouteServiceProvider قادرید، پیشوند و یا سایر گروه روت های خود را اصلاح نمایید.

Route های قابل قبول

روتر این فابلیت را در اختیار شما میگذارد تا به هر درخواست HTTP به درستی پاسخ دهید.

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);

گاهی ممکن است لازم باشد Route را تعریف کنید که به چندین درخواست HTTP پاسخ دهد. یرای این موارد می توانید از متد match برای درخواست هایی معین و یا متد any برای هر درخواستی مطابق با مثال زیر استفاده کنید.

Route::match(['get', 'post'], '/', function () {
    //
});

Route::any('/', function () {
    //
});

CSRF Protection

در لاراول هر فرم HTML که به action آن به روت های POST ، PUT ، PATCH یا DELETE اشاره دارد، باید شامل یک توکن فیلد CSRF باشد. در غیر این صورت، این درخواست توسط لاراول رد خواهد شد. فعلا این نکته را تا همین جا در نظر داشته باشید تا درباره روال استفاده ازCSRF در آموزش های بعدی بصورت مفصل توضیح دهم.

<form method="POST" action="/profile">
    @csrf
    ...
</form>

Redirect Routes

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

Route::redirect('/here', '/there');

به طور پیش فرض کد Route::redirect ری دایرکت را در وضعیت 302 انجام می دهد. شما می توانید بصورت مثال زیر وضعیت ری دایرکت مورد نظر را در پارامتر سوم سفارشی کنید.

Route::redirect('/here', '/there', 301);

برای ریدایرکت دائمی در وضعیت 301 می توانید از Route::permanentRedirect همانند مثال زیر استفاده نمایید.

Route::permanentRedirect('/here', '/there');

View Routes

در پیاده سازی یک پروژه ممکن است حالتی اتفاق بیافتد که Route شما فقط به یک View احتیاج داشته باشد، در این حالت لاراول Route::view را برای شما در نظر گرفته است، این حالت مانند حالت متد redirect یک میانبر ساده در اختیار شما می گذارد تا مجبور نشوید یک Route را با Controller تعریف کنید. متد view چند آرگومان را از شما دریافت میکند یک URI به عنوان اولین آرگومان و یک قالب view به عنوان دومین آرگومان از شما می پذیرد، همچنین شما می توانید آرایه ای از داده ها را برای انتقال به view به عنوان یک آرگومان سوم اختیاری قرار دهید مثال های زیر را بررسی فرمایید.

Route::view('/welcome', 'welcome');

Route::view('/welcome', 'welcome', ['name' => 'Taylor']);

پارامترها در Route

پارامتر های اجباری در Route

بعضی اوقات لازم است مقدار یک متغیر را از پارامتر های تعریف شده URI در route خود دریافت کنید. به عنوان مثال ، ممکن است لازم باشد id کاربر را از URL بگیرید. این کار را می توانید با تعریف پارامترها در مسیر انجام دهید.

Route::get('user/{id}', function ($id) {
    return 'User '.$id;
});

همچنین ممکن است تعداد پارامتر هایی که مد نظر دارید بیشتر از یک مورد باشد مانند مثالی که در زیر آورده شده است.

Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) {
    //
});

پارامترهای Route همیشه درون {} قرار می گیرند و نام گذاری آنها باید از حروف الفبای لاتین تشکیل شده باشند نکته مهم در اسامی پارامترها این است که شما مجاز به استفاده از کاراکتر خط تیره ( - ) نمی باشید و به جای استفاده از کاراکتر ( - ) باید از خط زیر (_) استفاده کنید. پارامترهای Route بر اساس ترتیب تعریف شدنشان به controller روت مورد نظر ارسال می شوند.

پارامترهای اختیاری در Route

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

Route::get('user/{name?}', function ($name = null) {
    return $name;
});

Route::get('user/{name?}', function ($name = 'John') {
    return $name;
});

اعمال محدودیت پارامترهای Route با عبارات منظم

شما می توانید مقادیر دریافتی از پارامتر Route را با استفاده از عبارات منظم و بکارگیری where محدود کنید. متد where نام پارامتر و مقدار مربوط به آن پارامتر را تحت یک عبارت منظم می پذیرد.

Route::get('user/{name}', function ($name) {
    //
})->where('name', '[A-Za-z]+');

Route::get('user/{id}', function ($id) {
    //
})->where('id', '[0-9]+');

Route::get('user/{id}/{name}', function ($id, $name) {
    //
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);

اعمال محدودیت عمومی در پارامتر Route

اگر می خواهید همیشه یک پارامتر در router با یک عبارت منظم خاص محدود شود، می توانید از متد pattern استفاده کنید. شما باید این pattern را در متدboot در RouteServiceProvider خود تعریف کنید.

/**
 * Define your route model bindings, pattern filters, etc.
 *
 * @return void
 */
public function boot()
{
    Route::pattern('id', '[0-9]+');
}

پس از تعریف pattern، محدودیت اعمال شده برای استفاده از آن نام پارامتر خاص به طور خودکار روی همه route ها اعمال می شود.

Route::get('user/{id}', function ($id) {
    // Only executed if {id} is numeric...
});

 استفاده از اسلش در پارامتر Route

لاراول در بکارگیری Route ها استفاده از تمامی کاراکتر ها در Route ها بلا مانع است بجر استفاده از اسلش . برای این منظور برای عبارت منظم در متد where را بصورت زیر بکار ببرید.

Route::get('search/{search}', function ($search) {
    return $search;
})->where('search', '.*');

نکته: استفاده از حالت مورد اشاره در بالا تنها برای پارامتر آخر در Route ها قابل استفاده است و در سایر موارد لاراول از آن پشتیبانی نمی کند.

نام گذاری Route ها

استفاده از نام گذاری Route ها سبب می شود تولید URL ها یا redirect به مسیری مشخص راحتر شود. شما می توانید با متد name یک نام خاص برای Route تعریف نماید.

Route::get('user/profile', function () {
    //
})->name('profile');

همچنین می توانید بصورت زیر هنگام تعریف یک controller برای یک Route نام آن روت را نیز تعریف نمایید.

Route::get('user/profile', [UserProfileController::class, 'show'])->name('profile');

نکته: اسامی تخصیص داده شده به هر Route باید یکتا و منحصر به فرد باشد.

ایجاد آدرس برای Route های نام گذاری شده

شما می توانید بصورت زیر به آدرس Route های نام گذاری شده دسترسی داشته باشید یا برای redirect به یک آدرس یک Route از اسم آن استفاده نمایید.

// Generating URLs...
$url = route('profile');

// Generating Redirects...
return redirect()->route('profile');

چنانچه برای Route نامگذاری شده پارامترهای مشخصی تعریف شده باشد بصورت زیر آن پارامتر ها و مقادیرشان را در redirect بکار خواهیم برد و پارامترهای و مقادیرشان به طور خودکار در موقعیت های صحیح خود در URL قرار خواهند گرفت.

Route::get('user/{id}/profile', function ($id) {
    //
})->name('profile');

$url = route('profile', ['id' => 1]);

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

Route::get('user/{id}/profile', function ($id) {
    //
})->name('profile');

$url = route('profile', ['id' => 1, 'photos' => 'yes']);

// /user/1/profile?photos=yes

چک کردن Route جاری

در لاراول به راحتی می توانید بررسی کنید که آیا درخواست فعلی از جانب یک Route معین هست یا خیر ؟ برای این منظور باید از متد named همانند مثال زیر استفاده کنید.

/**
 * Handle an incoming request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Closure  $next
 * @return mixed
 */
public function handle($request, Closure $next)
{
    if ($request->route()->named('profile')) {
        //
    }

    return $next($request);
}

گروه Route ها

گروه‌بندی روت ها به شما امکان می دهند ویژگی هایی مانند middleware را در Route ها را بصورت گروهی به اشتراک بگذارید، بدون آنکه نیاز باشد آن ویژگی را بصورت جداگانه برای تک تک روت های مد نظر خود بنوسید، این ویژگی های مشترک در قالب آرایه به عنوان اولین پارامتر در متد Route::group تعریف می شوند.

middleware در گروه Route ها

در لاراول می توانیم middleware را بصورت گروهی به تمام Route های داخل گروه اختصاص دهیم. برای این منظور ی توانیم از متد middleware استفاده کنیم.

Route::middleware(['first', 'second'])->group(function () {
    Route::get('/', function () {
        // Uses first & second middleware...
    });

    Route::get('user/profile', function () {
        // Uses first & second middleware...
    });
});

استفاده از Subdomain در Routing

همچنین می توان از گروه بندی Route ها برای مدیریت روت ها در ساب دامنه ها استفاده نمود. در این حالت می توان ساب دامین ها را به پارامترهای Route دقیقاً مانند URI های Route اختصاص داد، و به شما این امکان را می دهد بخشی از ساب دامنه خود را برای استفاده در Route یا Controller در نظر بگیرید.

Route::domain('{account}.myapp.com')->group(function () {
    Route::get('user/{id}', function ($account, $id) {
        //
    });
});

نکته: برای اطمینان از عدم تداخل Route های دامنه اصلی و Route های subdomain باید اول Route های ساب دامین و بعد از آن Route های دامنه اصلی را تعریف کنید، با اینکار از جایگزین شدن ناخواسته آن دسته از Route های ساب دامنه که URI هایی هم نام با دامنه اصلی دارند جلوگیری خواهد شد.

پیشوند Route ها در لاراول

از متد prefix می توان برای پیشوند هر Route در گروه Route ها با یک URI مشخص استفاده کرد. به عنوان مثال، ممکن است بخواهید تمام URI های Route را در یک روت گروه با پیشوند admin تعریف کنیم.

Route::prefix('admin')->group(function () {
    Route::get('users', function () {
        // Matches The "/admin/users" URL
    });
});

پیشوند های نام در Route ها

از متد name برای پیشوند هر نام Route در گروه با یک نام مشخص استفاده می شود. به عنوان مثال، ممکن است بخواهید تمام نام های Route ها در یک گروه با پشوند admin تعریف شوند. نام تخصیص داده شده باید بصورت String باشد و دقیقاً همانطور که در مثال زیر مشخص شده برای پیشوند نام Route ها لحاظ می گردد.

Route::name('admin.')->group(function () {
    Route::get('users', function () {
        // Route assigned name "admin.users"...
    })->name('users');
});

Route Model Binding

هنگام ارسال ID یک Model به Route یا Controller اغلب برای درخواست آن ID یک کوئری به Model مورد نظر برقرار می شود. Route Model Binding در لاراول راهی مناسب برای تزریق خودکار Model به طور مستقیم در Route های شما فراهم می کند، به عنوان نمونه در مثال زیر به جای ارسال ID کاربر ، می توانید کل نمونه Model کاربر را که با ID آن کاربر مطابقت دارد به Route ارسال کنید.

Implicit Binding

لاراول بطور خودکار مدل های تعریف شده در Route یا Controller را که نام آنها با نام متغیر در Route یکسان است را انطباق می دهد به مثال زیر دقت کنید.

Route::get('api/users/{user}', function (App\Models\User $user) {
    return $user->email;
});

از آنجا که متغیر user$ در مدل AppModelsUser با نام متغیر {user} در بخش URI مطابقت دارد، لاراول به طور خودکار مدلی را که دارای ID متناسب با مقدار دریافتی از URI است را جستجو و ایجاد می کند و اگر مدل منطبق با ID در پایگاه داده یافت نشود، به طور خودکار 404 HTTP ایجاد می شود.

سفارشی سازی کلید

بعضی اوقات ممکن است بخواهید مدلهای Eloquent را با استفاده از ستونی غیر از id ایجاد نمایید. برای این کار، می توانید ستون مورد نظر خود را در تعریف پارامتر Route مشخص کنید.

Route::get('api/posts/{post:slug}', function (App\Models\Post $post) {
    return $post;
});

سفارشی سازی Keys & Scoping

گاهی اوقات مجبوریم چندین مدل را در یک Route ایجاد نماییم، دراین حالت باید حتما مدل دوم فرزند مدل اول باشد. مثال زیر را در نظر بگیرید در این مثال یک پست وبلاگ را با استفاده از Slug برای یک کاربر خاص بازیابی می شود:

use App\Models\Post;
use App\Models\User;

Route::get('api/users/{user}/posts/{post:slug}', function (User $user, Post $post) {
    return $post;
});

هنگام استفاده از کلید سفارشی در implicit binding در پارامتر یک Route، لاراول به طور خودکار query را برای مدل فرزند بر مبنای رابطه اش با مدل والدین خود بازیابی می کند. در این مثال فرض بر این خواهد بود که مدل User رابطه ای به نام posts (اسم جمع پارامتر Route) دارد که می تواند برای بازیابی مدل Post استفاده شود.

سفارشی کردن نام کلید پیش فرض

اگر می خواهید برای استفاده از model binding از ستونی غیر از ID در پایگاه داده خود استفاده کنید، می توانید از متد getRouteKeyName بصورت زیر استفاده نمایید.

/**
 * Get the route key for the model.
 *
 * @return string
 */
public function getRouteKeyName()
{
    return 'slug';
}

Explicit Binding

برای بکار بردن Explicit Binding از متد model برای دریافت پارامتر های مورد نیاز در کلاس router استفاده می شود. برای این منظور باید از متد boot در کلاس RouteServiceProvider خود بصورت زیر استفاده نمایید:

/**
 * Define your route model bindings, pattern filters, etc.
 *
 * @return void
 */
public function boot()
{
    Route::model('user', App\Models\User::class);

    // ...
}

و بعد، یک Router با پارامتر {user} را تعریف کنید.

Route::get('profile/{user}', function (App\Models\User $user) {
    //
});

همان گونه که در بالا مشاهده کردید، تمام پارامترهای {user} را به مدل AppModelsUser وصل کرده ایم، و اکنون یک instance از User به Router ارسال می شود. به عنوان مثال، یک درخواست برای profile/1 یک instance از User را از پایگاه داده ای که دارای ID کاربر 1 است ایجاد می کند. اگر برای درخواستی یک instance در پایگاه داده یافت نشود ، پاسخ 404 HTTP به طور خودکار بازگردانده خواهد شد.