Чат PHP-разработчиков
Первая сущность. Создаём миграции и загружаем фикстуры. Работаем с шаблонизатором. Часть 2.

Первая сущность. Создаём миграции и загружаем фикстуры. Работаем с шаблонизатором. Часть 2.

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

Для начала создадим action posts(), который будет выводить все посты. Нам понадобится класс PostRepository, отвечающий за работу с таблицей постов. Однако в Symfony есть как минимум два способа работы с репозиторием. Поскольку мы унаследовались от AbstractController, мы можем достать репозиторий следующим образом и это будет первый способ:

Код доступен только после покупки курса по фреймворку Symfony 4.

То есть мы передаём в getRepository() в качестве переменной ссылку на сущность Post. Теперь $repo является объектом класса PostRepository, ему доступны все методы, предоставляемые стандартными репозиториями. Есть и другой способ, знакомый вам из курса по ООП, - внедрение зависимостей через конструктор. Я предпочитаю именно этот способ, однако вы вольны выбрать любой. На данном этапе класс контроллера выглядит так:

Код доступен только после покупки курса по фреймворку Symfony 4.

Пока ничего нового, обычное ООП. Но приступим же к первому экшену posts. Что нам нужно? Получить все записи и отправить их в шаблон. Создаём переменную $posts, в которой будем хранить результата выполнения запроса $this->postRepository->findAll(). Проще говоря, это массив записей, по которым мы пройдёмся в цикле в нашем шаблоне и достанем только названия статей. Наш action становится действительно полезным, а самое главное - ничего лишнего:

Код доступен только после покупки курса по фреймворку Symfony 4.

И не забудьте настроить маршрут, по которому мы будем видеть все посты. Думаю, этот экшен вы поймёте без проблем: получаем записи из репозитория и отправляем их в шаблон, который создался после создания контроллера.
Работать с циклами twig мы уже научились, так что делаем то же самое, что и на первом уроке:

Код доступен только после покупки курса по фреймворку Symfony 4.

Запускаем сервер командой php bin/console server:start и... видим ошибку. Да, Symfony ругается на то, что ему незнаком сервис Slugify из нашего прошлого урока. И правда, такого сервиса во фреймворке не существует. Но Symfony не был бы таким популярным, если бы легко не решал эту проблему. Для этого найдите файл config/services.yaml. В самом низу, на уровне с этой строкой App\Controller\ напишите следующее:

Код доступен только после покупки курса по фреймворку Symfony 4.

Это значит, что мы прямо указали, что класс AppFixtures принимает переменную $slugify, которая является объектом класса Cocur\Slugify\Slugify. Кто не понял, как это должно выглядеть, прилагаю скриншот:

Теперь запустите сервер ещё раз и перейдите по адресу, указанному в терминале, по маршруту /posts. Вы должны увидеть список наших постов. Теперь мы должны сделать возможность нажимать на ссылки и переходить к отдельной записи по её slug, чтобы увидеть контент. На самом деле, это делается даже легче, чем первый экшен, серьёзно. Я приведу его реализацию и объясню, что происходит:

Код доступен только после покупки курса по фреймворку Symfony 4.

В первую очередь обратите внимание на роутинг. Я уже упоминал в одном из первых уроков, что значения, заключенные в фигурные скобки, называются плейсхолдерами - они меняются в зависимости от запроса пользователя. А ещё, Symfony достаточно умный, чтобы понимать, по какому критерию вы достаёте данные, так что если вы напишите вместо slug id, title или body, он отдаст вам нужные данные конкретного поста! Всё это происходит благодаря аннотации ParamConverter, которую в нашем случае использовать необязательно.

Теперь переходим шаблон и пишем следующее:

Код доступен только после покупки курса по фреймворку Symfony 4.

Осталось только починить наши ссылки, чтобы можно было по ним переходить. Возвращаемся в шаблон posts/index.html.twig и меняем ссылку на новую:

Код доступен только после покупки курса по фреймворку Symfony 4.

Обратите внимание на href, мы использовали хелпер twig path(), который принимает в качестве аргументов имя маршрута (это те самые имена, которые мы указывали в аннотации Route, помните?) и второй аргумент для генерации динамического урла. В нашем случае это slug. В фигурных скобках мы пишем, что наш slug равен post.slug. Слишком много фигурных скобок, да, но вы к этому привыкните. Теперь вы можете обновить страницу и кликнуть на любую из ссылок. Если вы всё сделали правильно, вы увидите тело статьи.

Ну что же, мы сделали почти всё, чтобы написать своё первое CRUD приложение. Осталось познакомиться с формами, что мы и сделаем на следующем уроке.

Курс программирования на PHP
Подготовка до уровня устройства на работу!
Начать бесплатно
Комментарии (9)


valera

Подскажите, пож-ста, как мы получили в переменную $post конкретный пост?

 /**
     * @Route("/posts/{slug}", name="blog_show")
     */

 public function post (Post $post){
        return $this->render('posts/show.html.twig',[

        'post'=> $post]);
    }

т.е. понятно, что Symfony нашёл пост по уникальному идентификатору из роута, а дальше как в экшене он оказался под именем $post?

kafkiansky
cyprusscorpion

Цитата:
"Поскольку мы унаследовались от AbstractController, мы можем достать репозиторий следующим образом и это будет первый способ:
$repo = $this->getDoctrine()->getRepository(Post::class);"

А какое значение возвращает $this->getDoctrine()?

kafkiansky

$this->getDoctrine() возвращает ManagerRegistry. Узнать это можно, если в шторме кликнете на метод.

cyprusscorpion

Благодарю )

cyprusscorpion

Цитата:
"Возвращаемся в шаблон posts/index.html.twig и меняем ссылку на новую:

<a href="{{ path('blog_show', {'slug': post.slug}) }}">{{ post.title }}</a>".
Так мы в этом шаблоне и находимся, и только что написали в нем:

{% extends 'base.html.twig' %}

{% block body %}
    <p>{{ post.body }}</p>
{% endblock %}

Да, видимо не так просто эту "симфоническую мелодию" объяснить так, чтобы сразу все стало понятно ))

kafkiansky

Мы не в нем находимся. Это шаблон show.html.twig, а ссылка из index.html.twig.

cyprusscorpion

Цитирую:
"Теперь переходим в шаблон и пишем следующее:

{% extends 'base.html.twig' %}

{% block body %}
<p>{{ post.body }}</p>
{% endblock %}".
Какой шаблон??? Наверное, так и надо писать: "В шаблон show.html.twig..."
Да этот файл еще создать надо, или он автоматически создается?
Чайники приходят учиться, на них и рассчитывайте :))

valera

не в тот урок написал. переношу)

Самый понятный курс PHP
Онлайн-уроки в удобное время!
Начать бесплатно
Популярное за сутки
Онлайн-курсы PHP и MySQL
Обучение с полного нуля до уровня джуниора!
Начать бесплатно
Сейчас читают
Онлайн-курсы PHP и MySQL
Обучение с полного нуля до уровня джуниора!
Начать бесплатно
Новые статьи
Логические задачи с собеседований