تولید URL
- معرفی
- اصول اولیه
- آدرسهای اینترنتی برای مسیرهای نامگذاری شده
- آدرسهای اینترنتی برای اقدامات کنترلر
- مقادیر پیش فرض
معرفی
لاراول چندین کمک کننده برای کمک به شما در ایجاد URL برای برنامه خود ارائه می دهد. این کمکها در درجه اول هنگام ایجاد پیوند در قالبها و پاسخهای API یا هنگام ایجاد پاسخهای تغییر مسیر به قسمت دیگری از برنامه شما مفید هستند.
اصول اولیه
ایجاد URL
کمک
url
کننده ممکن است برای تولید URL های دلخواه برای برنامه شما استفاده شود. URL تولید شده به طور خودکار از طرح (HTTP یا HTTPS) و میزبان درخواست فعلی که توسط برنامه مدیریت می شود استفاده می کند:
$post = App\Models\Post::find(1); echo url("/posts/{$post->id}"); // http://example.com/posts/1
دسترسی به URL فعلی
اگر مسیری برای کمک کننده ارائه نشود
url
، یک
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 مسیر تغییر کند، نیازی به تغییر در تماس های شما با عملکرد نیست
. به عنوان مثال، تصور کنید برنامه شما حاوی مسیری است که به صورت زیر تعریف شده است:
route
Route::get('/post/{post}', function (Post $post) { // ...})->name('post.show');
برای ایجاد URL به این مسیر، می توانید از
route
راهنما مانند زیر استفاده کنید:
echo route('post.show', ['post' => 1]); // http://example.com/post/1
البته،
route
کمک کننده ممکن است برای تولید URL برای مسیرهایی با پارامترهای متعدد نیز استفاده شود:
Route::get('/post/{post}/comment/{comment}', function (Post $post, Comment $comment) { // ...})->name('comment.show'); echo route('comment.show', ['post' => 1, 'comment' => 3]); // http://example.com/post/1/comment/3
هر عنصر آرایه اضافی که با پارامترهای تعریف مسیر مطابقت ندارد به رشته پرس و جو URL اضافه می شود:
echo route('post.show', ['post' => 1, 'search' => 'rocket']); // http://example.com/post/1?search=rocket
مدل های الکوئنت
شما اغلب با استفاده از کلید مسیر (معمولاً کلید اصلی) مدلهای Eloquent
URL تولید میکنید
. به همین دلیل، می توانید مدل های Eloquent را به عنوان مقادیر پارامتر ارسال کنید. کمک
route
کننده به طور خودکار کلید مسیر مدل را استخراج می کند:
echo route('post.show', ['post' => $post]);
آدرس های اینترنتی امضا شده
لاراول به شما اجازه می دهد تا به راحتی URL های "امضا" را برای مسیرهای نامگذاری شده ایجاد کنید. این URL ها دارای یک هش "امضا" هستند که به رشته پرس و جو اضافه شده است که به لاراول اجازه می دهد تا تأیید کند که URL از زمان ایجاد آن تغییر نکرده است. URL های امضا شده مخصوصاً برای مسیرهایی مفید هستند که عموماً در دسترس هستند اما به لایه ای از محافظت در برابر دستکاری URL نیاز دارند.
به عنوان مثال، ممکن است از URL های امضا شده برای پیاده سازی پیوند عمومی "لغو اشتراک" استفاده کنید که برای مشتریان شما ایمیل می شود. برای ایجاد یک URL امضا شده برای یک مسیر نامگذاری شده، از
signedRoute
روش نما استفاده کنید
URL
:
use Illuminate\Support\Facades\URL; return URL::signedRoute('unsubscribe', ['user' => 1]);
absolute
میتوانید با ارائه آرگومان به روش
، دامنه را از هش URL امضا شده خارج کنید
signedRoute
:
return URL::signedRoute('unsubscribe', ['user' => 1], absolute: false);
اگر می خواهید یک URL مسیر امضا شده موقت ایجاد کنید که پس از مدت زمان مشخصی منقضی می شود، می توانید از این
temporarySignedRoute
روش استفاده کنید. وقتی لاراول یک URL مسیر امضا شده موقت را تأیید می کند، اطمینان حاصل می کند که مهر زمانی انقضا که در URL امضا شده کدگذاری شده است، سپری نشده است:
use Illuminate\Support\Facades\URL; return URL::temporarySignedRoute( 'unsubscribe', now()->addMinutes(30), ['user' => 1]);
اعتبار سنجی درخواست های مسیر امضا شده
برای تأیید اینکه یک درخواست ورودی دارای امضای معتبر است، باید
hasValidSignature
متد موجود در نمونه ورودی را فراخوانی کنید
Illuminate\Http\Request
:
use Illuminate\Http\Request; Route::get('/unsubscribe/{user}', function (Request $request) { if (! $request->hasValidSignature()) { abort(401); } // ...})->name('unsubscribe');
گاهی اوقات، ممکن است لازم باشد به صفحهنمایش برنامهتان اجازه دهید تا دادهها را به یک URL امضاشده اضافه کند، مانند هنگام انجام صفحهبندی سمت مشتری. بنابراین، میتوانید پارامترهای پرس و جوی درخواستی را مشخص کنید که هنگام تأیید اعتبار یک URL امضا شده با استفاده از
hasValidSignatureWhileIgnoring
روش، نادیده گرفته شوند. به یاد داشته باشید، نادیده گرفتن پارامترها به هر کسی اجازه می دهد تا آن پارامترها را در درخواست تغییر دهد:
if (! $request->hasValidSignatureWhileIgnoring(['page', 'order'])) { abort(401);}
به جای اعتبارسنجی URL های امضا شده با استفاده از نمونه درخواست ورودی، می توانید
میان افزار
signed
(
Illuminate\Routing\Middleware\ValidateSignature
) را
به مسیر اختصاص دهید. اگر درخواست دریافتی دارای امضای معتبر نباشد، میان افزار به طور خودکار یک
پاسخ HTTP برمی گرداند:
403
Route::post('/unsubscribe/{user}', function (Request $request) { // ...})->name('unsubscribe')->middleware('signed');
اگر URL های امضا شده شما دامنه را در هش URL شامل نمی شود، باید آرگومان را
relative
به میان افزار ارائه دهید:
Route::post('/unsubscribe/{user}', function (Request $request) { // ...})->name('unsubscribe')->middleware('signed:relative');
پاسخگویی به مسیرهای امضا شده نامعتبر
هنگامی که شخصی از یک URL امضا شده بازدید می کند که منقضی شده است، یک صفحه خطای عمومی برای کد وضعیت HTTP دریافت می کند
403
. با این حال، میتوانید این رفتار را با تعریف یک بسته «رندر» سفارشی برای
InvalidSignatureException
استثنا در فایل برنامه خود سفارشی کنید
bootstrap/app.php
:
use Illuminate\Routing\Exceptions\InvalidSignatureException; ->withExceptions(function (Exceptions $exceptions) { $exceptions->render(function (InvalidSignatureException $e) { return response()->view('error.link-expired', [], 403); });})
آدرسهای اینترنتی برای اقدامات کنترلر
تابع
action
یک URL برای عملکرد کنترلر داده شده ایجاد می کند:
use App\Http\Controllers\HomeController; $url = action([HomeController::class, 'index']);
اگر متد کنترلر پارامترهای مسیر را بپذیرد، می توانید یک آرایه ارتباطی از پارامترهای مسیر را به عنوان آرگومان دوم به تابع ارسال کنید:
$url = action([UserController::class, 'profile'], ['id' => 1]);
مقادیر پیش فرض
برای برخی از برنامهها، ممکن است بخواهید مقادیر پیشفرض درخواستی را برای پارامترهای URL خاص مشخص کنید. به عنوان مثال، تصور کنید بسیاری از مسیرهای شما یک
{locale}
پارامتر را تعریف می کنند:
Route::get('/{locale}/posts', function () { // ...})->name('post.index');
دست و پا گیر است که همیشه
locale
هر بار که با کمک تماس می گیرید عبور کنید
route
. بنابراین، می توانید از
URL::defaults
روش برای تعریف یک مقدار پیش فرض برای این پارامتر استفاده کنید که همیشه در طول درخواست فعلی اعمال می شود. ممکن است بخواهید این روش را از
میان افزار مسیر
فراخوانی کنید تا به درخواست فعلی دسترسی داشته باشید:
<?php namespace App\Http\Middleware; use Closure;use Illuminate\Http\Request;use Illuminate\Support\Facades\URL;use Symfony\Component\HttpFoundation\Response; class SetDefaultLocaleForUrls{ /** * Handle an incoming request. * * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next */ public function handle(Request $request, Closure $next): Response { URL::defaults(['locale' => $request->user()->locale]); return $next($request); }}
هنگامی که مقدار پیشفرض پارامتر
locale
تنظیم شد، دیگر لازم نیست مقدار آن را هنگام تولید URL از طریق
route
Helper ارسال کنید.
پیشفرضهای URL و اولویت میانافزار
تنظیم مقادیر پیشفرض URL میتواند در مدیریت لاراول از اتصالات مدل ضمنی اختلال ایجاد کند. بنابراین، باید
میانافزار خود را
که پیشفرض URLها را قبل از میانافزار لاراول اجرا میکند، اولویت بندی کنید
SubstituteBindings
. شما می توانید این کار را با استفاده از
priority
روش میان افزار موجود در فایل برنامه خود انجام دهید
bootstrap/app.php
:
->withMiddleware(function (Middleware $middleware) { $middleware->priority([ \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class, \Illuminate\Cookie\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class, \Illuminate\Contracts\Auth\Middleware\AuthenticatesRequests::class, \Illuminate\Routing\Middleware\ThrottleRequests::class, \Illuminate\Routing\Middleware\ThrottleRequestsWithRedis::class, \Illuminate\Session\Middleware\AuthenticateSession::class, \App\Http\Middleware\SetDefaultLocaleForUrls::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, \Illuminate\Auth\Middleware\Authorize::class, ]);})