Роуты (маршрутизация)
Большинство роутов (маршруты, routes) вашего приложения будут определены в файле app/routes.php . В Laravel простейший роут состоит из URI (урла, пути) и функции-замыкания (она же коллбек).
Простейший GET-роут:
Route::get('/', function() < return 'Hello World'; >);
Простейший POST-роут:
Route::post('foo/bar', function() < return 'Hello World'; >);
Регистрация роута для нескольких методов
Route::match(array('GET', 'POST'), '/', function() < return 'Hello World'; >);
Регистрация роута для любого типа HTTP-запроса:
Route::any('foo', function() < return 'Hello World'; >);
Регистрация роута, всегда работающего через HTTPS:
Route::get('foo', array('https', function() < return 'Must be over HTTPS'; >));
Вам часто может понадобиться сгенерировать URL к какому-либо роуту — для этого используется метод URL::to :
$url = URL::to('foo');
Здесь ‘foo’ — это URI.
Параметры роутов
Route::get('user/', function($id) < return 'User '.$id; >);
Необязательные параметры роута:
Route::get('user/', function($name = null) < return $name; >);
Необязательные параметры со значением по умолчанию:
Route::get('user/', function($name = 'John') < return $name; >);
Роуты с соответствием пути регулярному выражению:
Route::get('user/', function($name) < // >) ->where('name', '[A-Za-z]+'); Route::get('user/', function($id) < // >) ->where('id', '[0-9]+');
Конечно, при необходимости вы можете передать массив ограничений (constraints):
Route::get('user//', function($id, $name) < // >) ->where(array('id' => '[0-9]+', 'name' => '[a-z]+'))
Определение глобальных паттернов
Вы можете определить соответствие параметра пути регулярному выражению глобально для всех роутов. Например, если у вас в урлах это всегда числовое значение:
Route::pattern('id', '[0-9]+'); Route::get('user/', function($id) < // Only called if is numeric. >);
Доступ к значению параметров роута
Если вам нужно получить значение параметра роута не в нем, а, где-то еще, например, в фильтре или контроллере, то вы можете использовать Route::input() :
Route::filter('foo', function() < if (Route::input('id') == 1) < // > >);
Фильтры роутов
Фильтры — удобный механизм ограничения доступа к определённому роуту, что полезно при создании областей сайта только для авторизованных пользователей. В Laravel изначально включено несколько фильтров, в том числе auth , auth.basic , guest and csrf . Они определены в файле app/filters.php .
Регистрация фильтра маршрутов:
Route::filter('old', function() < if (Input::get('age') < 200) < return Redirect::to('home'); > >);
Если фильтр возвращает значение, оно используется как ответ фреймворка (response) на сам запрос (request) и обработчик маршрута не будет вызван, и все after -фильтры тоже будут пропущены.
Привязка фильтра к роуту:
Route::get('user', array('before' => 'old', function() < return 'You are over 200 years old!'; >));
Сочетания фильтра и привязки роута к контроллеру
Route::get('user', array('before' => 'old', 'uses' => 'UserController@showProfile'));
Привязка нескольких фильтров к роуту
Route::get('user', array('before' => 'auth|old', function() < return 'You are authenticated and over 200 years old!'; >));
Привязка нескольких фильтров к роуту при помощи массива
Route::get('user', array('before' => array('auth', 'old'), function() < return 'You are authenticated and over 200 years old!'; >));
Передача параметров для фильтра
Route::filter('age', function($route, $request, $value) < // >); Route::get('user', array('before' => 'age:200', function() < return 'Hello World'; >));
Фильтры типа after (выполняющиеся после запроса, если он не был отменён фильтром before — прим. пер.) получают $response как свой третий аргумент:
Route::filter('log', function($route, $request, $response) < // >);
Фильтры по шаблону
Вы можете также указать, что фильтр применяется ко всем роутам, URI (путь) которых соответствует шаблону.
Route::filter('admin', function() < // >); Route::when('admin/*', 'admin');
В примере выше фильтр admin будет применён ко всем маршрутам, адрес которых начинается с admin/ . Звёздочка (*) используется как символ подстановки и соответствует любому набору символов, в том числе пустой строке.
Вы также можете привязывать фильтры, зависящие от типа HTTP-запроса:
Route::when('admin/*', 'admin', array('post'));
Классы фильтров
Для продвинутой фильтрации вы можете использовать классы вместо функций-замыканий. Так как такие фильтры будут создаваться с помощью IoC-контейнера, то вы можете использовать внедрение зависимостей (Dependency Injection) для лучшего тестирования.
Определение класса для фильтра:
Route::filter('foo', 'FooFilter');
По умолчанию будет вызван метод filter класса FooFilter :
class FooFilter < public function filter() < // Логика фильтра. > >
Вы можете изменить это дефолтное поведение и указать метод явно:
Route::filter('foo', 'FooFilter@foo');
Именованные роуты
Присваивая имена роутам вы можете сделать обращение к ним (при генерации URL во вьюхах (views) или переадресациях) более удобным. Вы можете задать имя роуту таким образом:
Route::get('user/profile', array('as' => 'profile', function() < // >));
Также можно указать контроллер и его действие:
Route::get('user/profile', array('as' => 'profile', 'uses' => 'UserController@showProfile'));
Теперь вы можете использовать имя маршрута при генерации URL или переадресации:
$url = URL::route('profile'); $redirect = Redirect::route('profile');
Получить имя текущего выполняемого маршрута можно методом currentRouteName :
$name = Route::currentRouteName();
Группы роутов
Иногда вам может быть нужно применить фильтры к набору маршрутов. Вместо того, чтобы указывать их для каждого маршрута в отдельности вы можете сгруппировать маршруты:
Route::group(array('before' => 'auth'), function() < Route::get('/', function() < // К этому маршруту будет привязан фильтр auth. >); Route::get('user/profile', function() < // К этому маршруту также будет привязан фильтр auth. >); >);
Внутри группы вы можете указать параметр namespace , чтобы не прописывать неймспейсы к каждому контроллеру:
Route::group(array('namespace' => 'Admin'), function() < // >);
Поддоменные роуты
Роуты Laravel способны работать и с поддоменами по их маске и передавать в ваш обработчик параметры из шаблона.
Регистрация роута по поддомену:
Route::group(array('domain' => '.myapp.com'), function() < Route::get('user/', function($account, $id) < // >); >);
Префикс пути
Группа роутов может быть зарегистрирована с одним префиксом в URL без его явного указания, с помощью ключа prefix в параметрах группы.
Route::group(array('prefix' => 'admin'), function() < Route::get('user', function() < // >); >);
Привязка моделей к роутам
Привязка моделей — удобный способ передачи экземпляров моделей в ваш роут. Например, вместо передачи ID пользователя вы можете передать модель User, которая соответствует данному ID, целиком. Для начала используйте метод Route::model для указания модели, которая должна быть использована вместо данного параметра.
Привязка параметра к модели
Route::model('user', 'User');
Затем зарегистрируйте маршрут, который принимает параметр :
Route::get('profile/', function(User $user) < // >);
Из-за того, что мы ранее привязали параметр к модели User , то её экземпляр будет передан в маршрут. Таким образом, к примеру, запрос profile/1 передаст объект User , который соответствует ID 1 (полученному из БД — прим. пер.).
Внимание: если переданный ID не соответствует строке в БД, будет брошено исключение (Exception) 404.
Если вы хотите задать свой собственный обработчик для события «не найдено», вы можете передать функцию-замыкание в метод model :
Route::model('user', 'User', function() < throw new NotFoundHttpException; >);
Иногда вам может быть нужно использовать собственный метод для получения модели перед её передачей в маршрут. В этом случае просто используйте метод Route::bind :
Route::bind('user', function($value, $route) < return User::where('name', $value)->first(); >);
Ошибки 404
Есть два способа вызвать исключение 404 (Not Found) из маршрута. Первый — методом App::abort :
App::abort(404);
Второй — бросив исключение класса или потомка класса Symfony\Component\HttpKernel\Exception\NotFoundHttpException .
Больше информации о том, как обрабатывать исключения 404 и отправлять собственный ответ на такой запрос содержится в разделе об ошибках.
Роуты в контроллер
Laravel позволяет вам регистрировать маршруты не только в виде функции-замыкания, но и классов-контроллеров и даже создавать контроллеры ресурсов.
Больше информации содержится в разделе о контроллерах.
Русскоязычное комьюнити
- Группа в VK
- Телеграм LaravelRUS
- Телеграм Laravel для новичков
- Телеграм LaravelPro
Обучающие ресурсы
- Laracasts
- Codecourse
- Курс Дмитрия Елисеева
- Adam Wathan
Блоги разработчиков
- Laravel News
- Freek Van der Herten
- Brent Roose
- Marcel Pociot
Что такое Symfony Route (роуты). Маршрутизация.
Одно из основных понятий Symfony, с которым желательно познакомиться — это такое понятие как route (роут). Давайте будем разбираться, что это такое.
route — это просто путь, по которому мы можем обратиться к ресурсу (контрольной точке) внутри Symfony.
Когда мы создали какой-то сайт, у этого сайта есть его доменное имя. Например, site.ru. Есть путь к конкретному ресурсу, который мы запрашиваем (например, category/first).
category/first — это и есть тот самый route.
route — это тот конкретный путь до того ресурса, к которому мы хотим с вами обратиться. Это тот путь, который должен ввести пользователь в адресную строку браузера, чтобы у него открылось какое-то определенное содержимое.
route = путь + ресурс, который будет обрабатывать контроллер.
Где создаются routes
Как правило, роуты создаются внутри контроллера, но есть еще вариант хранения роута в конфигурационных файлах. Роуты, по сути, это просто настройки для symfony, который говорят какой метод внутри класса контроллера соответствует какому-то пути в вашем проекте.
Создание роутов внутри контроллера
Если мы говорим о создании роутов внутри контроллера, здесь есть 2 основных способа. Более устаревший способ: с помощью аннотаций. Этот способ использовался до Symfony версии 6.
Выглядит это следующим образом:
/** * @Route(«/blog>», name=»blog_show») */ public function showAction()
Аннотации — это просто особым образом оформленные PHP комментарии. Они должны обязательно располагаться над методом, к которому они относятся.
Symfony умеет воспринимать эти аннотации и понимает, что это настройки роута и нужно использовать их для метода, который располагается ниже.
С появлением Symfony 6 и PHP 8, использование аннотаций в коде является устаревшей формой создания роутов внутри контроллера. Как правило, сейчас используется конструкция атрибутов.
Выглядит это следующим образом:
#[Route('/wb_keys', name: 'wb_keys')] public function test(): Response < return $this->render('wb_keys.html.twig',[]); >
Это немного более сокращенная форма записи и в отличии от аннотаций ее можно записать одной строкой.
Здесь используется конструкция #[настройки]
Создание routes в конфигурационных файлах.
Кроме создания роутов в контроллере, есть также возможность их создания внутри файлов конфигурации.
Главный настроечный файл для создания роутов config/routes.yaml. В этом файле мы также можем прописать какие роуты будут в нашей системе. Например,
post_show: path: /posts controller: 'App\Controller\DefaultController::showPost'
path — создает путь для роута, а controller указывает ссылку на тот контроллер и метод внутри него, который будет вызывать при обращении по этому адресу.
В общих чертах, это основы создания Symfony routes (роутов). Здесь есть еще много особенностей и тонкостей работы, с которыми мы будем разбираться в следующих видео. Давайте на практике создадим первый роут и первый контроллер и посмотрим, как это у нас будет работать.
Дмитрий Ченгаев
Занимаюсь заказной веб-разработкой. Подписывайтесь на телеграм канал https://t.me/dchengaev 😉
2023-03-12
Чтобы оставить сообщение, зарегистрируйтесь/войдите на сайт через:
Настройка роутинга
Эта статья имеет отношение к вам, если для подключения к интернету вы устанавливаете соединение с интернетом с именем пользователя и паролем, и у вас нет роутера. Если интернет у вас есть сразу, как только вы включили компьютер — роутинг вам настраивать не нужно! Если вы подключаетесь через роутер — настраивать нужно, но совсем по другому. Статью об этом мы обязательно напишем чуть позже.
Что такое роутинг, и зачем он нужен?
Роутинг — это набор правил, которые указывают вашему компьютеру, через какие сервера можно получить доступ к различным ресурсам. Если не настраивать рутинг специально, то ваш компьютер знает только один «маршрут по умолчанию» (default route), который выдается ему автоматически. Если VPN-соединение (подключение к интернету) отключено, то маршрут по умолчанию — это адрес нашего коммутатора, через него вы не можете получить доступ в интернет, а только к локальным ресурсам сети, IP-телевидению, и к ресурсам пиринга. Когда вы подключатесь к интернету, установив VPN-соединение с использованием имени и пароля — маршрутом по умолчанию становится адрес нашего VPN-сервера, и запросы к любым ресурсам ваш компьютер отправляет на этот адрес.
Зачем настраивать роутинг?
В настоящее время сложилась такая ситуация, что интернет-провайдерам, расположенным относительно недалеко друг от друга, гораздо дешевле передавать информацию между собой не через вышестоящего магистрального провайдера (который может пересылать через Америку информацию, которая на самом деле должна быть передана в соседний район), а установив прямое соединение друг с другом. Это называется пиринг. Поскольку такой траффик относительно дешев для провайдера, мы предоставляем его вам в подарок! То есть — совершенно бесплатно, и без ограничений скорости. То есть вы можете получить доступ к ресурсам пиринга, не устанавливая соединения с интернетом, и даже при отрицательном балансе. Однако, тут возникает одна проблема — если вы хотите одновременно работать и с интернетом, и с ресурсами пиринга — то скорость скачивания с пиринговых ресурсов будет ограничиватся согласно вашему тарифному плану, и локальный трафик будет списыватся с баланса, как обычный интернетовский. Так происходит из за того самого маршрута по умолчанию, других ведь ваш компьютер не знает. Как быть? Очень просто! Надо научить его другим маршрутам, то есть показать, что для локальных ресорсов он должен обращатся на адрес коммутатора, а для всех остальных — на адрес VPN-сервера.Это и называется — прописать роутинг, или маршрутизацию.
Кроме пиринга, прописывать роутинг обязательно нужно, если вы хотите смотреть IP-телевидение.
Routes. The Beginning
Роуты в рельсах очень важная вещь. Но до поры до времени можно даже не обращать внимание на них. Особенно если вы пользуетесь командой scaffold, которая автоматически все прописывает. Но в какой-то момент появляется необходимость создавать нестандартные роуты. Это значит самое время залезать в файл routes.rb в папке config вашего проекта.
Что такое роуты
Роуты — это система маршрутов (путей, url’ов) на вашем сайте. Благодаря роутам мы можем иметь красивые и ясные для пользователей ссылки. Введя ссылку вроде mysite.ru/articles/2008/november/13 мы получим все статьи за 13 ноября 2008 года, а по ссылке mysite.ru/shop/shoes получим каталог обуви из вашего магазина. При всем при этом, структура каталогов сайта никак не изменяется. В любой момент мы можем изменить роуты не трогая расположение самих файлов. Но чтобы все это работало нам необходимо настроить роуты.
К практике
Давайте создадим тестовый проект, с которым мы будем шаманить. (Если вы это делает впервые, то можно обсудить в комментариях процесс установки рельс и создания приложения).
rails routes
cd routes
Окей. Проект создан и мы вошли в рабочую папку. Сразу набросимся на роуты:
эта команда вам выдаст две строчки стандартных роутов.
/:controller/:action/:id
/:controller/:action/:id.:format
Это значит, что любой урл сейчас будет парситься по этим двум правилам.
:controller — это Контроллер =). Это компонент MVC, который чаще всего выступает как посредник между Представлением (HTML) и Моделью (база данных, скажем). Дальше будет яснее, но скорее всего вы итак знаете, что это такое.
:action — это вызываемый метод контроллера. У контроллера обычно много методов.
:id — если я вно не указывать запрет на создание id, то по умолчанию любая модель (таблица БД) создается с полем id. Поэтому любой элемент модели имеет id. И когда вы хотите удалить/редактировать/что угодно делать с каким-то конкретным элементом модели вы обязаны передать в контроллер этот самый id.
Окей. Давайте мы создадим новостной журнал. Для этого нам нужны:
— Таблица news в нашей базе данных (Модель). В БД мы будем хранить заголовок статьи (title), автора статьи (author) и собственно саму статью (article)
— Набор методов для работы с БД (Контроллер)
— HTML формы для ввода, редактирования, чтения новостей (Представление)
Мы можем создавать все это по отдельности. Но сейчас мы упростим себе задачу и используем функцию scaffold для генерации пачки готовых файлов.
./script/generate scaffold Magazine title:string author:string article:text
Мы только что создали все выше перечисленное (а также Helpers, о которых как-нибудь в другой раз). Также команда scaffold сама создала необходимые роуты. Еще раз наберите команду rake routes и вывалится кипа новых роутов
magazines GET /magazines "magazines", :action=>"index"> formatted_magazines GET /magazines.:format "magazines", :action=>"index"> POST /magazines "magazines", :action=>"create"> POST /magazines.:format "magazines", :action=>"create"> new_magazine GET /magazines/new "magazines", :action=>"new"> formatted_new_magazine GET /magazines/new.:format "magazines", :action=>"new"> edit_magazine GET /magazines/:id/edit "magazines", :action=>"edit"> formatted_edit_magazine GET /magazines/:id/edit.:format "magazines", :action=>"edit"> magazine GET /magazines/:id "magazines", :action=>"show"> formatted_magazine GET /magazines/:id.:format "magazines", :action=>"show"> PUT /magazines/:id "magazines", :action=>"update"> PUT /magazines/:id.:format "magazines", :action=>"update"> DELETE /magazines/:id "magazines", :action=>"destroy"> DELETE /magazines/:id.:format "magazines", :action=>"destroy">
Теперь мы запустим сервер и поиграемся с журналом. Но сперва мы создадим нашу базу данных и запустим миграции.
rake db:create
rake db:migrate
./script/server
Наш журнал теперь доступен по адресу localhost:3000/magazines
Создайте пару новых статей.
Вернемся к таблице роутов выше. Первый столбец — это именные роуты. Они очень удобны. Есть несколько вариантов сейчас сделать ссылку на создание новой статьи. Откройте файл app/views/magazines/index.html.erb — это представление для метода index в контроллере magazines_controller.
В самом низу давайте допишем немного кода.
Самым правильным будет использование последних двух методов. Разница в том, что url возвращает полную ссылку (http://localhost:3000/magazines/new), а path только путь (/magazines/new). Почему лучше пользоваться именными роутами? Именной роут это переменная, изменив которую вы меняете все ссылки, которые пользуются этим роутом. Писать пути от руки вобще не рекомендуется, если приспичило, то лучше написать :action => ‘new’ (зачастую именных роутов на все случаи жизне не хватает, поэтому этот вариант очень распространен).
Второй столбец таблицы — это метод запроса. Одна и таже ссылка, но с разным методом ведет на разные методы контроллера. К примеру, в том же app/views/magazines/index.html.erb:
:delete %>
В первой ссылке исполняется дефолтный GET запрос (можно не указывать в ссылке :method=>:get), а во второй отправляется метод :delete. А ссылка magazine остается в обоих случаях одинаковая.
Третий столюбец — это собственно ссылки, которые мы получим в HTML. Последний столбец — это соответствие ссылок контроллеру и методу. Как уже выше писалось, любую ссылку можно представить в виде пары :controller, :action (ну и иногда :method).
‘blogs’, :action=>’show’, :id=>’1′, :method=>’GET’ %>
Так мы получим ссылку на блог с индексом 1. (Тут метод :get можно было и не указывать)
‘show’, :id => ‘1’ %>
Ссылка на статью с индексом 1. Контроллер и HTTP метод в данном случае указывать не надо, так как GET исполняется по умолчанию, а контроллер, если не указан, выполняется тот же.
Тепрь откройте файл config/routes.rb (можете удалить весь закомментированный текст)
map.resources :magazines
map.connect ‘:controller/:action/:id’
map.connect ‘:controller/:action/:id.:format’
Первую строчку вставила команда scaffold. Эта строчка и добавила нам пачку роутов, которую мы наблюдали выше.
Если вы сейчас наберете просто localhost:3000 вы попадете на приветственную страницу. Давайте это исправим.
map.root :controller => ‘magazines’
Теперь из папки public удалите index.html и зайдя на localhost:3000 вы попадете напрямую куда надо =). Кроме того если вы просмотрите все роуты занова (rake routes), то увидите новый именной роут root. И в меню сможете сделать ссылку на «Главную» вида:
И вы всегда без ущерба ссылкам сможете изменить домашнюю страницу, скажем, на ваш магазин map.root :controller => ‘shop’
II уровень
Собственно создав root вы создали первый именной роут своими руками.
Давайте создадим именной роут «localhost:3000/zhurnal». Не хотим мы буржуйский ‘magazines’, хотим ‘zhurnal’!
map.zhurnal ‘/klevi_zhurnal/:id’, :controller => ‘magazines’, :id => nil
Итак, мы создали именной роут zhurnal, урл которого будет выглядеть как localhost:3000/klevi_zhurnal, а контент он будет получать от контроллера magazines. Если мы попробуем прочесть статью теперь вроде localhost:3000/klevi_zhurnal/1 — то мы обламаемся. Внесем в наш роут немного изменений:
map.zhurnal ‘/klevi_zhurnal/:action/:id’, :controller => ‘magazines’, :action => ‘index’, :id => nil
Что все это значит:
— урл вида /klevi_zhurnal/ будет отработан :controller => ‘magazines’, :action => ‘index’, :id => ‘nil’ — то есть мы получим индексовую страницу (index.html.erb)
— /klevi_zhurnal/1 выплюнет ошибку, что action ‘1’ не существует (посмотрите на последовательность передачи аргумента в роуте)
— /klevi_zhurnal/show скажет, что ID не указано
— /klevi_zhurnal/show/1 — выдаст вам статью с (если она конечно существует)
— /klevi_zhurnal/edit/1 — выдаст форму редактирования этой статьи
Обратите внимание на то, что для лучшего понимания роутов введена система множественного/единственного числа:
показать все статьи magazines_path,
показать отдельную статью: magazine_path.
Чорт — не самое правильное слово вообще выбрал =). Если бы у нас все называлось Article:
index => articles_path, show => article_path(:id)
Теперь давайте создадим новый метод.
Откройте app/controllers/magazines_controller.rb
Добавьте туда метод
def random
offset = rand(Magazine.count :all)
@magazine = Magazine.find(:first, :offset => offset)
render :action => ‘show’
end
Этот метод просто возвращает рандомно статью. Давайте попробуем его вызвать: localhost:3000/magazines/random
Получаем ошибку — требует от нас ID. Почему? Потому что стандартный роут продразумевает роут вида :controller/:action/:id.
Давайте попробуем вызвать роут по правилам:
localhost:3000/magazines/random/1230492
Записи с таким ID не существует — но все работает! Так как мы в нашем методе не используем ID вообще — то для нас и не принципиально какую ерунду мы там напишем.
Давайте теперь все же попробуем сделать корректный роут вида localhost:3000/magazines/random/
Для этого существует опция :collection => < :action =>:HTTP_method >
Наш :action это :random, метод — :get
получаем
map.resources :magazines, :collection => < :random =>:get >
теперь все работает! =)
На этом вводная часть заканчивается. Дальше нас ждут более изощренные методы извращения ). Но не сегодня.
Спасибо, за потраченное на чтение статьи время ).