пользователей: 30398
предметов: 12406
вопросов: 234839
Конспект-online
РЕГИСТРАЦИЯ ЭКСКУРСИЯ

Маршрутизация. Параметры маршрутов

Простейшая маршрутизация

Все маршруты (routes) определены в файле app/Http/routes.php, который автоматически загружается фреймворком. В Laravel простейшие маршруты принимают URI (путь) и функцию-замыкание, предоставляя очень простой и выразительный метод определения маршрутов:

+ 5.2

добавлено в 5.2 (08.12.2016)

Route::get('foo', function () {

  return 'Hello World';

});

Файл маршрутов по умолчанию

Файл routes.php загружается провайдером RouteServiceProvider и автоматически включается в группу посредников web, что обеспечивает доступ к состоянию сессии и CSRF-защиту. Большинство маршрутов вашего приложения будут определены в этом файле.

Доступные методы маршрутизатора

Маршрутизатор позволяет регистрировать маршруты для любого 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);

Иногда необходимо зарегистрировать маршрут, который отвечает на HTTP-запросы нескольких типов. Это можно сделать методом match(). Или вы можете зарегистрировать маршрут, отвечающий на HTTP-запросы всех типов, с помощью метода any():

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

  //

});



Route::any('foo', function () {

  //

});

+ 5.1 5.0

добавлено в 5.1 (19.06.2016) 5.0 (08.02.2016)

Route::get('/', function () {

  return 'Hello World';

});



Route::post('foo/bar', function () {

  return 'Hello World';

});



Route::put('foo/bar', function () {

  //

});



Route::delete('foo/bar', function () {

  //

});

Регистрация маршрута для нескольких типов запросов

Иногда необходимо зарегистрировать маршрут, который отвечает на HTTP-запросы нескольких типов. Это можно сделать методом match() фасада Route:

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

  return 'Hello World';

});

Или вы можете зарегистрировать маршрут, отвечающий на HTTP-запросы всех типов, с помощью метода any():

Route::any('foo', function () {

  return 'Hello World';

});

Генерирование адресов URL для маршрутов

Вы можете генерировать URL для маршрутов вашего приложения методом url():

$url = url('foo');

Параметры маршрутов

Обязательные параметры

Разумеется, иногда вам может понадобиться захватить сегменты URI в вашем маршруте. Например, если вам необходимо захватить ID пользователя из URL. Это можно сделать, определив параметры маршрута:

Route::get('user/{id}', function ($id) {

  return 'User '.$id;

});

Вы можете определить сколько угодно параметров:

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

  //

});

Параметры маршрута всегда заключаются в фигурные скобки. Параметры будут переданы в замыкание вашего маршрута при выполнении маршрута.

Параметры маршрута не могут содержать символ -. Используйте вместо него подчёркивание _.

Необязательные параметры маршрута

Иногда необходимо указать параметр маршрута, но при этом сделать его наличие необязательным. Это можно сделать, поместив знак вопроса ? после названия параметра. Не забудьте задать значение по умолчанию для соответствующей переменной маршрута:

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

  return $name;

});



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

  return $name;

});

Ограничения регулярными выражениями

Вы можете ограничить формат параметров вашего маршрута с помощью метода 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]+']);

Глобальные ограничения

Если вы хотите, чтобы параметр был всегда ограничен заданным регулярным выражением, то можете использовать метод pattern(). Вам следует определить эти шаблоны в методе boot() вашего RouteServiceProvider:

/**

 * Определение привязок вашей модели, шаблонов фильтрации и т.д.

 *

 * @param  \Illuminate\Routing\Router  $router

 * @return void

 */

public function boot(Router $router)

{

  $router->pattern('id', '[0-9]+');



  parent::boot($router);

}

Когда шаблон определён, он автоматически применяется ко всем маршрутам, использующим этот параметр:

Route::get('user/{id}', function ($id) {

  // Вызывается только если {id} числовой.

});

+ 5.0

добавлено в 5.0 (08.02.2016)

Доступ к значению параметра маршрута

Если вам нужен доступ к значению параметра маршрута извне, то вы можете использовать метод input():

if ($route->input('id') == 1)

{

  //

}

Также вы можете получить параметры текущего маршрута через экземпляр Illuminate\Http\Request. Получить объект текущего запроса можно через фасад Request или указав тип Illuminate\Http\Request, в котором внедрены зависимости:

use Illuminate\Http\Request;



Route::get('user/{id}', function(Request $request, $id)

{

  if ($request->route('id'))

  {

    //

  }

});

Именованные маршруты

Именованные маршруты позволяют удобно генерировать URL-адреса и делать переадресацию на конкретный маршрут. Вы можете задать имя маршруту с помощью ключа массива as:

Route::get('user/profile', ['as' => 'profile', function () {

  //

}]);

Также можно указать имена маршрутов для действий контроллера:

Route::get('user/profile', [

  'as' => 'profile', 'uses' => 'UserController@showProfile'

]);

Или, вместо указания имени маршрута в определении массива маршрутов вы можете «прицепить» метод name() к определению маршрута:

Route::get('user/profile', 'UserController@showProfile')->name('profile');

+ 5.0

добавлено в 5.0 (08.02.2016)

Метод currentRouteName() возвращает имя маршрута, обрабатывающего текущий запрос:

$name = Route::currentRouteName();

Группы маршрутов и именованные маршруты

Если вы используете группы маршрутов, то можете использовать ключ as в массиве атрибутов группы маршрутов, так вы можете задать общий префикс для имён маршрутов в группе:

Route::group(['as' => 'admin::'], function () {

  Route::get('dashboard', ['as' => 'dashboard', function () {

    // Маршрут назван "admin::dashboard"

  }]);

});

Генерирование URL адресов для именованных маршрутов

Когда вы назначили имя маршруту, вы можете использовать это имя для генерирования URL адресов и переадресаций глобальным методом route():

// Генерирование URL...

$url = route('profile');



// Генерирование переадресаций...

return redirect()->route('profile');

Если у именованного маршрута есть параметры, вы можете передать их вторым аргументом метода route(). Эти параметры будут автоматически вставлены в соответствующие места URL:

Route::get('user/{id}/profile', ['as' => 'profile', function ($id) {

  //

}]);



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

Группы маршрутов

Группы маршрутов позволяют использовать общие атрибуты маршрутов, такие как посредники и пространства имён, для большого числа маршрутов без необходимости определять эти атрибуты для каждого отдельного маршрута. Общие атрибуты указываются в виде массива первым аргументом метода Route::group().

Мы поговорим подробнее о группах маршрутов, рассматривая типичные случаи их применения.

Посредники

Посредники применяются ко всем маршрутам в группе путём указания списка этих посредников с параметром middleware в массиве групповых атрибутов. Посредники будут выполнены в порядке их указания в этом массиве:

Route::group(['middleware' => 'auth'], function () {

  Route::get('/', function ()    {

    // Использует посредника Auth

  });



  Route::get('user/profile', function () {

    // Использует посредника Auth

  });

});

Пространства имён

Другой типичный пример использования групп маршрутов — назначение одного пространства имён PHP для группы контроллеров. Вы можете использовать параметр namespace в массиве групповых атрибутов для указания пространства имён для всех контроллеров в группе:

Route::group(['namespace' => 'Admin'], function()

{

  // Контроллеры в пространстве имён "App\Http\Controllers\Admin"



  Route::group(['namespace' => 'User'], function() {

    // Контроллеры в пространстве имён "App\Http\Controllers\Admin\User"

  });

});

Помните, по умолчанию RouteServiceProvider включает файл routes.php в группу пространства имён, позволяя вам регистрировать маршруты контроллера без указания полного префикса пространства имён App\Http\Controllers. Поэтому нам надо указать лишь ту часть пространства имён, которая следует за базовым пространством имён App\Http\Controllers.

Доменная маршрутизация

Группы маршрутов можно использовать для масок маршрутов поддоменов. Поддоменам можно назначать параметры маршрутов также как URI маршрутов, поэтому вы можете захватить часть поддомена и использовать в своём маршруте или контроллере. Поддомен можно указать с помощью ключа domain в массиве атрибутов группы:

Route::group(['domain' => '{account}.myapp.com'], function () {

  Route::get('user/{id}', function ($account, $id) {

    //

  });

});

Префиксы маршрута

Атрибут группы prefix можно использовать для указания URI-префикса каждого маршрута в группе. Например, если вы хотите добавить admin ко всем URI маршрутов в группе:

Route::group(['prefix' => 'admin'], function () {

  Route::get('users', function ()    {

    // Соответствует URL "/admin/users"

  });

});

Вы также можете использовать параметр prefix для передачи общих параметров в ваши сгруппированные маршруты:

Route::group(['prefix' => 'accounts/{account_id}'], function () {

  Route::get('detail', function ($accountId)    {

    // Соответствует URL "accounts/{account_id}/detail"

  });

});

+ 5.0

добавлено в 5.0 (08.02.2016)

Вы можете даже определить ограничения для именованного параметра в вашем префиксе:

Route::group([

  'prefix' => 'accounts/{account_id}',

  'where' => ['account_id' => '[0-9]+'],

], function() {



  // Здесь определение маршрутов

});

CSRF-защита

Введение

В Laravel легко защитить ваше приложение от CSRF-атаки межсайтовой подделки запросов. Межсайтовая подделка запроса — тип вредоносных атак, при котором неавторизованные команды выполняются от имени авторизованного пользователя.

Laravel автоматически генерирует CSRF-"токен" для каждой активной сессии пользователя в приложении. Этот токен используется для проверки того, что запрос в приложение отправляет именно авторизованный пользователь.

Каждый раз определяя HTML-форму в своём приложении, вы должны включать в неё скрытое поле CSRF-токена, чтобы посредник CSRF-защиты смог проверить запрос. Чтобы сгенерировать скрытое поле ввода _token, содержащее CSRF-токен, используйте вспомогательную функцию csrf_field():

// Vanilla PHP

<?php echo csrf_field(); ?>



// Blade Template Syntax

{{ csrf_field() }}

Функция csrf_field() генерирует такой HTML:

<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">

Вам не нужно вручную проверять CSRF-токен в запросах типа POST, PUT или DELETE. посредник VerifyCsrfToken, который входит в группу посредников web, будет автоматически проверять совпадение токена входящего запроса с токеном, хранящимся в сессии.

Исключение URI из CSRF-защиты

Иногда бывает необходимо исключить набор URI из CSRF-защиты. Например, при использовании Stripe для обработки платежей и их системы веб-хуков вам необходимо исключить ваш маршрут обработчика веб-хуков из CSRF-защиты Laravel.

Вы можете исключить URI, определив их маршруты вне группы посредников web, которая включена в файл по умолчанию routes.php, или добавив эти URI в свойство $except посредника VerifyCsrfToken:

<?php



namespace App\Http\Middleware;



use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;



class VerifyCsrfToken extends BaseVerifier

{

  /**

   * URI, которые надо исключить из проверки CSRF.

   *

   * @var array

   */

  protected $except = [

    'stripe/*',

  ];

}

X-CSRF-TOKEN

Кроме поиска CSRF-ключа в параметрах «POST», посредник VerifyCsrfToken также проверит наличие заголовка запроса X-CSRF-TOKEN. Например, вы можете хранить ключ в теге «meta»:

<meta name="csrf-token" content="{{ csrf_token() }}">

Когда вы создали тег meta, вы можете добавлять токен в заголовки всех запросов с помощью библиотеки, такой как jQuery. Так обеспечивается простая и удобная CSRF-защита для ваших приложений на основе AJAX:

$.ajaxSetup({

      headers: {

        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')

      }

});

X-XSRF-TOKEN

Laravel также хранит CSRF-ключ в cookie XSRF-TOKEN. Вы можете использовать значение из cookie, чтобы задать заголовок запроса X-XSRF-TOKEN. Некоторые фреймворки JavaScript, такие как Angular, делают это автоматически. Вряд ли вам придётся использовать это значение вручную.

Разница между X-CSRF-TOKEN и X-XSRF-TOKEN в том, что первый использует простое текстовое значение, а второй — шифрованное значение, т.к. cookie в Laravel всегда шифруются. Если для передачи значения ключа вы используете функцию csrf_token(), то вам вероятно нужно использовать заголовок X-CSRF-TOKEN.

Привязка модели

Привязка моделей — удобный способ внедрения экземпляров модели в ваши маршруты. Например, вместо внедрения ID пользователя вы можете внедрить весь экземпляр модели User, который соответствует данному ID.

+ 5.2

добавлено в 5.2 (08.12.2016)

Неявная привязка

Laravel автоматически включит те модели Eloquent, определённые в действиях маршрута или контроллера с помощью указания типов, чьи переменные имеют имена, совпадающие с сегментом маршрута. Например:

Route::get('api/users/{user}', function (App\User $user) {

  return $user->email;

});

В этом примере Laravel автоматически внедрит экземпляр модели, который имеет ID, совпадающий с соответствующим значением из URI запроса, потому что переменная Eloquent $user, определённая в маршруте, совпадает с сегментом URI маршрута {user}.

Если совпадающий экземпляр модели не найден в базе данных, будет автоматически сгенерирован HTTP-отклик 404.

Изменение имени ключа

Если вы хотите, чтобы для получения моделей при неявной привязке вместо столбца id использовался другой столбец базы данных, вы можете переопределить метод getRouteKeyName() в своей модели Eloquent:

/**

 * Получить ключ маршрута для модели.

 *

 * @return string

 */

public function getRouteKeyName()

{

  return 'slug';

}

Явная привязка

Для регистрации явной привязки используйте метод маршрута model() для указания класса для данного параметра. Вам надо определить привязки вашей модели в методе RouteServiceProvider::boot().

Привязка параметра к модели

public function boot(Router $router)

{

  parent::boot($router);



  $router->model('user', 'App\User');

}

Затем определите маршрут, содержащий параметр {user}:

$router->get('profile/{user}', function(App\User $user) {

  //

});

+ 5.0

добавлено в 5.0 (08.02.2016)

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

{

  //

});

Из-за того, что мы ранее привязали параметр {user} к модели App\User, её экземпляр будет внедрён в маршрут. Таким образом, к примеру, запрос profile/1 внедрит объект User, который соответствует ID 1 (полученному из БД — прим. пер.).

Если совпадающий экземпляр модели не найден в базе данных, будет автоматически сгенерирован HTTP-отклик 404.

+ 5.2

добавлено в 5.2 (08.12.2016)

Изменение логики принятия решения

Если вы хотите использовать свою логику принятия решения, используйте метод Route::bind(). Переданное вами в метод bind() замыкание получит значение сегмента URI и должно вернуть экземпляр класса, который вы хотите внедрить в маршрут:

$router->bind('user', function ($value) {

  return App\User::where('name', $value)->first();

});

Изменение поведения при событии «не найдено»

Если вы хотите задать свой собственный обработчик для события «не найдено», вы можете передать функцию-замыкание в качестве третьего аргумента метода model():

$router->model('user', 'App\User', function() {

  throw new NotFoundHttpException;

});

+ 5.0

добавлено в 5.0 (08.02.2016)

Route::model('user', 'User', function()

{

  throw new NotFoundHttpException;

});

Если захотите использовать собственную логику обработки, используйте метод Route::bind(). Переданное в метод bind() замыкание получит значение сегмента URI, и должно вернуть экземпляр класса, который вы хотите внедрить в маршрут:

$router->bind('user', function($value) {

  return App\User::where('name', $value)->first();

});

+ 5.0

добавлено в 5.0 (08.02.2016)

Route::bind('user', function($value)

{

  return User::where('name', $value)->first();

});

Подмена методов

HTML-формы не поддерживают действия PUT, PATCH и DELETE. Поэтому при определении маршрутов PUT, PATCH и DELETE, вызываемых из HTML-формы, вам надо добавить в неё скрытое поле _method. Переданное в этом поле значение будет использовано как метод HTTP-запроса:

<form action="/foo/bar" method="POST">
  <input type="hidden" name="_method" value="PUT">
  <input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>

Для создания скрытого поля _method вы также можете использовать функцию method_field():

<?php echo method_field('PUT'); ?>

Конечно, если вы используете шаблонизатор Blade:

{{ method_field('PUT') }}

+ 5.2

добавлено в 5.2 (08.12.2016)

Получение текущего маршрута

Метод Route::current() вернёт маршрут, обрабатывающий текущий HTTP-запрос, позволяя вам проверить весь экземпляр Illuminate\Routing\Route:

$route = Route::current();



$name = $route->getName();



$actionName = $route->getActionName();

Также вы можете использовать вспомогательные методы currentRouteName() и currentRouteAction() фасада Route, чтобы получить имя или действие текущего маршрута:

$name = Route::currentRouteName();

$action = Route::currentRouteAction();

Чтобы изучить все доступные методы, обратитесь к документации по API класса, лежащего в основе фасада Route, и экземпляра Route.

+ 5.1 5.0

добавлено в 5.1 (19.06.2016) 5.0 (08.02.2016)

Ошибки 404

Есть два способа вручную вызвать исключение 404 (Not Found) из маршрута. Первый — методом abort(), который просто вызывает Symfony\Component\HttpFoundation\Exception\HttpException с указанным кодом состояния:

abort(404);

Второй — вручную вызвав экземпляр Symfony

 


22.06.2017; 17:27
хиты: 160
рейтинг:0
для добавления комментариев необходимо авторизироваться.
  Copyright © 2013-2024. All Rights Reserved. помощь