Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Ресурсная маршрутизация PHP: Разработка на Laravel

Фактически, любой CRUD состоит из 7 маршрутов, контроллера и шаблонов. Причем большая часть этого кода идентична, особенно маршруты. Они не содержат логики и всегда строятся по одному и тому же принципу.

Laravel частично заимствовал из Rails еще один механизм, который называется "ресурсная маршрутизация". Он упрощает создание типичных CRUD, за счет полной унификации всех маршрутов и способов их обработки. Вместо описания 7 разных маршрутов, ресурсная маршрутизация позволяет указать один метамаршрут:

<?php

Route::resource('articles', ArticleController::class);

Внутри себя он превращается в те самые семь маршрутов, которые мы реализовывали в предыдущих уроках. Их можно увидеть с помощью команды artisan:

php artisan route:list

+-----------+-------------------------+------------------+---------+
| Method    | URI                     | Name             | Action  |
+-----------+-------------------------+------------------+---------+
| GET|HEAD  | /                       |                  | Closure |
| GET|HEAD  | articles                | articles.index   | index   |
| POST      | articles                | articles.store   | store   |
| GET|HEAD  | articles/create         | articles.create  | create  |
| GET|HEAD  | articles/{article}      | articles.show    | show    |
| PUT|PATCH | articles/{article}      | articles.update  | update  |
| DELETE    | articles/{article}      | articles.destroy | destroy |
| GET|HEAD  | articles/{article}/edit | articles.edit    | edit    |
+-----------+-------------------------+------------------+---------+
# Обратите внимание на имя плейсхолдера. Ниже станет понятно почему здесь article, а не id

Довольно неплохо. В проектах где подобных CRUD много (любой типичный веб-проект), ресурсный маршрутизатор очень помогает. Он не просто сокращает количество кода, но и дает хорошую унификацию. Нужно меньше думать и меньше спорить. Все уже спроектировано.

Следующий шаг – упрощение контроллера. Во-первых, можно сразу сгенерировать контроллер, со всеми нужными обработчиками. Во-вторых, этот контроллер можно интегрировать с нужной моделью:

php artisan make:controller ArticleController --resource --model Article

На выходе получим такой контроллер:

<?php

namespace App\Http\Controllers;

use App\Models\Article;
use Illuminate\Http\Request;

class ArticleController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\Models\Article  $article
     * @return \Illuminate\Http\Response
     */
    public function show(Article $article)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\Models\Article  $article
     * @return \Illuminate\Http\Response
     */
    public function edit(Article $article)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\Models\Article  $article
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, Article $article)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\Models\Article  $article
     * @return \Illuminate\Http\Response
     */
    public function destroy(Article $article)
    {
        //
    }
}

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

Ресурсы могут быть вложенными. Это дает возможность строить пути, отражающие зависимости между сущностями на сайте:

# Примеры с Хекслета

# Урок /courses/{course}/lessons/{lesson}
/courses/js-testing/lessons/asserts
# Список пройденных курсов /u/{user}/courses
/u/mokevnin/courses

Принцип построения адресов точно такой же, как и для обычного ресурса, но с включением указания на родительский ресурс:

# Список
/entities/{entity}/subentities

# Сущность
/entities/{entity}/subentities/{subentity}

# Все остальные маршруты строятся по такому же принципу.
# Впереди добавляется /entities/{entity}.

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

php artisan make:controller ArticleCommentController --resource --model ArticleComment --parent Article

Например, вот так выглядит ресурс комментарии к статьям:

<?php

Route::resource('articles.comments', ArticleCommentController::class);

Для вложенного ресурса, в экшены, кроме самой сущности передается и родительская сущность:

<?php

# /articles/{article}/comments/{comment}
# Обе сущности можно получить через параметры
public function edit(Article $article, ArticleComment $comment)
{
    return view('article_comment.edit', compact('article', 'comment'));
}

Если ресурс называется articles.comments, то параметр следует назвать $comment, а не $articleComment. Другими словами, имя параметра выбирается в единственном числе по имени ресурса.

Немного по-другому начинает работать хелпер route. Для построения ссылок, там где участвуют оба ресурса, нужно использовать массив для их передачи:

<?php

route('articles.comments.edit', [$article, $comment]);

Заключение

Ресурсная маршрутизация – удобный механизм, позволяющий немного упростить создание CRUD. Он берет на себя много работы и дает программисту возможность сосредоточиться на логике.

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


Самостоятельная работа

  1. Удалите все маршруты связанные со статьями
  2. Удалите контроллер статей (шаблоны оставьте)
  3. Добавьте ресурсную маршрутизацию articles
  4. Сгенерируйте для него контроллер ArticleController
  5. Реализуйте CRUD

Дополнительные материалы

  1. Ресурсная маршрутизация
  2. Полезные практики для работы с Laravel

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

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

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
Занимайтесь созданием сайтов, веб-приложений, сервисов и их интеграцией с внутренними бизнес-системами на бекенд-языке PHP
10 месяцев
с нуля
Старт 21 ноября

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»