تولید URL

مجتبی پاکزاد لاراول 5.6.29 در حال تکمیل رایگان

مقدمه

لاراول هلپرهای مختلفی را ارائه می‌کند که با کمک آن‌ها، می‌توانید URLهای مورد نظرتان را جهت استفاده در اپلیکیشن خود تولید کنید. البته، این فانکشن‌ها به خصوص زمانی که می‌خواهید لینک‌هایی را در تمپلت‌ها و ریسپانس‌های API بسازید، یا هنگامی که ریسپانس‌های ریدایرکت به بخش‌های دیگر اپلیکیشن‌تان تولید می‌کنید، مفید هستند.

اصول اولیه

تولید URLهای پایه

هلپر url می‌تواند بری تولید URLهای دلخواه اپلیکیشن‌تان استفاده شود. URL تولید شده به صورت خودکار از اسکیمایی (HTTP یا HTTPS) استفاده می‌کند که از ریکوئست جاری به دست می‌آید.

$post = App\Post::find(1);

echo url("/posts/{$post->id}");

// http://example.com/posts/1

دسترسی به URL جاری

اگر هیچ مسیری (path) به هلپر url ارسال نشود، یک نمونه (instance) از Illuminate\Routing\UrlGenerator برگردانده می‌شود، که به شما امکان دسترسی به اطلاعات URL جاری را می‌دهد:

// Get the current URL without the query string...
echo url()->current();

// Get the current URL including the query string...
echo url()->full();

// Get the full URL for the previous request...
echo url()->previous();

همچنین با استفاده از فساد URL می‌توان به هر کدام از این متدها دسترسی داشت:

use Illuminate\Support\Facades\URL;

echo URL::current();

URLهای مربوط به مسیرهای نامگذاری شده

هلپر route می‌تواند برای تولید URL مربوط به مسیرهای نامگذاری شده استفاده گردد. مسیرهای نامگذاری شده به شما این امکان را می‌دهند تا بدون وصل شدن به URL واقعیِ تعریف شده در مسیر، URLهای مورد نظرتان را تولید کنید. بنابراین، اگر URL مسیری عوض شود، نیازی به تغییر در کد فراخوانی فانکشن route خود ندارید. برای مثال، فرض کنید اپلیکیشن‌تان حاوی مسیری تعریف شده به شکل زیر است:

Route::get('/post/{post}', function () {
    //
})->name('post.show');

برای تعریف یک URL برای این مسیر، می‌توانید از هلپر route به شکل زیر استفاده کنید:

echo route('post.show', ['post' => 1]);

// http://example.com/post/1

اغلب URLها را با توجه به primary key مدل‌های الوکوئنت تولید می‌کنید. به همین دلیل، می‌توانید مدل‌های الوکوئنت را به عنوان مقادیر پارامتر ارسال کنید. هلپر route به صورت خودکار primary key مدل‌ها را استخراج می‌کند:

echo route('post.show', ['post' => $post]);

URLهای ساین‌شده

لاراول به شما امکانی را ارائه می‌دهد تا به راحتی برای مسیرهای نامگذاری شده، URL ساین‌شده (Signed) ایجاد کنید. این URLها هش یک signature (علامت مشخص) را به کوئری استرینگ اضافه می‌کنند که به لاراول این امکان را می‌دهد تا تایید کند که آیا این URL از زمان ایجاد تا به حال، مورد دسترسی قرار نگرفته باشد یا خیر. URLهای ساین‌شده، به خصوص برای مسیرهایی که به صورت عمومی در دسترس هستند اما هنوز برای جلوگیری از دستکاری و سواستفاده از URL نیاز به حفاظت از آن است، مفید هستند.

برای مثال، می‌توانید از URLهای ساین‌شده برای پیاده‌سازی یک لینک "لغو اشتراک" عمومی استفاده کنید که به مشتریان خود از طریق ایمیل ارسال کرده‌اید. برای ساخت یک URL ساین‌شده برای یک مسیر نامگذاری شده، از متد signedRoute فساد URL استفاده کنید:

use Illuminate\Support\Facades\URL;

return URL::signedRoute('unsubscribe', ['user' => 1]);

اگر مایلید که URL مسیر ساین‌شده‌ی موقت تولید کنید که منقضی شود، می‌توانید از متد استفاده temporarySignedRoute کنید:

use Illuminate\Support\Facades\URL;

return URL::temporarySignedRoute(
    'unsubscribe', now()->addMinutes(30), ['user' => 1]
);

اعتبارسنجی ریکوئست‌های مربوط به مسیرهای ساین‌شده

برای تایید اینکه ریکوئست ورودی دارای یک signature معتبر است، باید متد hasValidSignature را بر روی Request ورودی فراخوانی کنید:

use Illuminate\Http\Request;

Route::get('/unsubscribe/{user}', function (Request $request) {
    if (! $request->hasValidSignature()) {
        abort(401);
    }

    // ...
})->name('unsubscribe');

یا به صورت جایگزین، می‌توانید میدلور Illuminate\Routing\Middleware\ValidateSignature را به مسیر (route) خود تخصیص دهید. اگر این میدلور در آرایه routeMiddleware کرنل HTTP خود کلیدی نداشته باشد، باید یک کلید برای آن تعیین کنید.

/**
 * The application's route middleware.
 *
 * These middleware may be assigned to groups or used individually.
 *
 * @var array
 */
protected $routeMiddleware = [
    'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
];

هنگامی که میدلور را در کرنل اپلیکیشن خود رجیستر کردید، می‌توانید آن را به مسیر خود متصل (attach) کنید. اگر ریکوئست وارده، دارای signature معتبری نباشد، میدلور به صورت خودکار یک ریسپانس خطای 403 برمی‌گرداند:

Route::post('/unsubscribe/{user}', function (Request $request) {
    // ...
})->name('unsubscribe')->middleware('signed');

URLهایی برای اکشن‌های کنترلر

فانکشن action برای اکشن مشخصی از کنترلر مورد نظرتان URL تولید می‌کند. نیازی به ارسال تمام نیم‌اسپیس ندارید. به جای آن، نام کلاس کنترلر را نسبت به App\Http\Controllers ارسال کنید:

$url = action('HomeController@index');

اگر متد کنترلر مورد نظر، پارامترهای مسیر را قبول می‌کند، می‌توانید آن‌ها را به عنوان آرگومان دوم به این فانکشن پاس دهید:

$url = action('UserController@profile', ['id' => 1]);

مقادیر پیش‌فرض

برای برخی از اپلیکیشن‌ها، ممکن است بخواهید برای پارامترهای URL مشخصی، مقادیر پیش‌فرضی برای ریکوئست تعیین کنید. برای مثال، فرض کنید تعداد زیادی از مسیرهای‌تان یک پارامتر {locale} را تعریف می‌کنند.

Route::get('/{locale}/posts', function () {
    //
})->name('post.index');

اینکه همواره و هر زمان که هلپر route را فراخوانی می‌کنید، locale را نیز پاس دهید، کمی دست و پاگیر است. بنابراین، می‌توانید از متد URL::defaults استفاده کنید تا مقدار پیش‌فرضی برای این پارامتر تعریف کنید تا همیشه در طول درخواست جاری اعمال شود. ممکن است بخواهید این متد را از یک میدلور مسیر فراخوانی کنید تا بتوانید به درخواست جاری دسترسی داشته باشید:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\URL;

class SetDefaultLocaleForUrls
{
    public function handle($request, Closure $next)
    {
        URL::defaults(['locale' => $request->user()->locale]);

        return $next($request);
    }
}

هنگامی که برای پارامتر locale مقادیر پیش‌فرض تنظیم شود، دیگر در هنگام تولید URLها به وسیله هلپر route، مجبور نیستید مقدار آن را ارسال کنید.

منبع
URL Generation