Генерация URL

Содержание:


Введение

Laravel включает несколько помощников, чтобы помочь вам в генерировании URL для вашего приложения. Это наиболее полезно, при создании ссылок в шаблонах и API ответах, или при генерации ответа в виде перенаправления на другую страницу приложения.


Основы

Генерация базовых URL-адресов

Помощник url может быть использован для генерации URL для вашего приложения. Сгенерированный URL будет автоматически использовать схему (HTTP или HTTPS) и хост из текущего запроса:

$post = App\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 определённому в маршруте. Таким образом, если изменился URL, вам не потребуется вносить измения в вызов функции route. Например, представим что ваше приложении содержит маршрут определённый таким образом:

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

Чтобы сгенерировать URL для этого маршрута, вы можете использовать помощник route так:

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

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

Вам часто потребуется сгенерировать URL используя первичный ключ модел Eloquent. По этомй причине, вы можете передать модель Eloquent как значение параметра. Помощник route поможет автоматически получить первичный ключ модели:

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

Помощник route также может быть использован, чтобы сгенерировать URL для маршрутов с несколькими параметрами:

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

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

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

Подписание URL-адресов

Laravel позволяет вам легко создать "подписанный" URL для названного маршрута. Эти URL имеют хэш-подпись, которая добавляется в строку запроса, что позволяет Laravel верефицировать то, что данный URL не был модифицирован с момента создания. Подписанные URL могут быть особенно полезны для публичных маршрутов, которые нуждаются в дополнительном слое защиты.

Например, вы использовали подписанные URL для того, чтобы реализовать публичную ссылку "отписаться от рассылки", которая высылается пользователю на электронную почту. Чтобы создать подписанный URL для названного маршрута, используйте метод signedRoute для URL фасада:

use Illuminate\Support\Facades\URL;

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

Если вы хотите сгенерировать временно подписанный маршрут, который исчезнет, вы можете использовать метод temporarySignedRoute:

use Illuminate\Support\Facades\URL;

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

Валидация подписанных запросов маршрута

Чтобы верефицировать, что входящий запрос имеет валидную подпись, вы должны вызвать метод hasValidSignature для входящего запроса:

use Illuminate\Http\Request;

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

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

Как альтернатива, вы можете приписать к маршруту посредника Illuminate\Routing\Middleware\ValidateSignature. Если такого пока нет, вы должны приписать ключ посредника в массиве routeMiddleware:

/**
 * 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,
];

После регистрации посредника, его можно прикреплять к маршруту. Если входящий запрос не имеет валидной подписи, посредник автоматически вернёт ошибку 403 в качестве ответа:

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

URL-адреса для действий контроллера

Функция action генерирует URL для данного действия контроллера. Вам не нужно передавать пространство имён полностью. Вместо этого, передайте в контроллер имя класса относительно просторанста имён App\Http\Controllers:

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

Вы также можете ссылаться на действия с помощью "вызываемого" синтаксиса массива:

use App\Http\Controllers\HomeController;

$url = action([HomeController::class, 'index']);

Если контроллер принимает параметры маршрута, вы можете передать их как второй аргумент в функцию:

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

Значения по умолчанию

Для некоторых ваших приложений, вы можете захотеть задать значение по умолчанию для определйнных параметров URL в контексте всего запроса. Например, представьте, что большое количество маршрутов определяют параметр {locale}:

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

Громоздко всегда передавать locale каждый раз, когда вы вызываете помощник route. Поэтому, вы можете использовать метод URL::defaults, чтобы определить значение по умолчанию для данного параметра, которое всегда будет доступно в течение текущего запроса. Вы можете вызвать этот метод через посредника маршрута, при этом у вас останется доступ к текущему запросу:

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.