Сайт FSA
14.02.2024

Symfony

Долгое время не решался попробовать фреймворки. Писал свой, который должен был быть лучше, чем у других. Наверно многие так делают. Пока писал код, разбирался что и как устроено у других. И настал тот момент, когда мне надоело постоянно переделывать код своих проектов под новую версию своего фреймворка. А переделывать часто нужно было очень много.

К тому времени, как я решился попробовать фреймворки, у меня был выбор из двух мастодонтов: Laravel и Symfony. Laravel попробовал первым. Но он показался мне несколько перегруженным. Symfony же привлёк тем, то он модульный. Многие из его компонентов могут работать отдельно от фреймворка. К тому же часть компонентов Symfony используется в Laravel!!! Это ли не реклама качества кода, что даже «конкурент» пользуется твоими услугами.

Версионирование у Symfony довольно интересное. На момент моего знакомства с проектом была актуальна версия 6.3. Чуть позже вышли версии 6.4 и 7.0. Такой расклад оказался кстати, это позволило мне понять какую версию фреймворка выбрать.

Номер версии состоит из трёх чисел, например, 6.4.1. Старшее число говорит о том, что в этой версии удалены все устаревшие возможности, которые присутствовали в ранней версии. Это позволяет очистить код от излишнего мусора, который когда-то был полезным, но теперь не несёт полезной нагрузки и нужен только для совместимости со старыми версиями. Увеличение второго числа говорит о том, что в коде появились новые возможности и, возможно, какой-то код устарел. При этом вы будете получать предупреждения в логах, что вы используете что-то устаревшее и это необходимо исправить до перехода на новую версию (число в первом разряде номера версии). Третье число в номере версии самое безобидное. Это просто корректирующие релизы, где ничего не менялось, но были исправлены какие-то ошибки или недоработки.

Таким образом, передо мной встал выбор между версиями 6.4.* и 7.0.*. С одной стороны 6.4 тянет за собой весь груз устареваний, которые в новом проекте не будут использоваться. С другой стороны минимальные требования к версии PHP у 6.4PHP 8.1, а для 7.0PHP 8.2. Если не использовать контейнеры, а пользоваться обычной виртуальной машиной на Ubuntu, то версию PHP 8.2 до выхода Ubuntu 24.04 LTS будет затруднительно. Точнее потребуется подключать сторонние репозитории, что не очень удобно и безопасно.

Таким образом при выборе версии фреймворка лучше руководствоваться следующими принципами:

  1. выбирать самую новую версию фреймворка;
  2. убедиться, что эта версия способна работать на вашем сервере, т.е. поддерживает ли он необходимую версию PHP.

Как вы видите, те, кто пользуется контейнерами в плюсе. Они всегда могут использовать последнюю актуальную версию фреймворка.

С другой стороны, вы можете совершенно безболезненно перейти с версии 6.4 на 7.0, если ваш код не выдаёт никаких предупреждений об устаревании. Однако при обновлении с версии 6.0 до 7/0 могу возникнуть проблемы. Необходимо обновиться предварительно до версии 6.4, проверить что вашем коде устарело, исправить это и, уже потом, переходить на 7.0.

Создание проекта

Для старта нового проекта достаточно загрузить готовый скелет приложения c помощью composer, с нужной версией фреймворка, например:

composer create-project symfony/skeleton:"7.0.*" ИМЯ_ПРОЕКТА

Новый проект будет состоять из нескольких каталогов и файлов. Каталоги:

Файлы:

Ставим разом всё необходимое для веб-приложения

Можно установить множество полезных пакетов для веб-приложения одной командой

composer require webapp

Будут установлены, например:

и множество других.

Файлы конфигурации

Файлы конфигурации Symfony поддерживают множество форматов. Это может быть как php код или yaml файлы, так и xml. Чаще всего используется конфигурация в формате yaml. Это довольно удобный формат для понимания человеком. Однако, в некоторых случаях удобно использовать и другие форматы, например, файлы php.

Для начала необходимо познакомиться с форматом yaml, т.к. в скелете проекта этот формат интенсивно используется.

Мои первые проблемы с проектом

Первая проблема, с которой я столкнулся — непонятные ошибки при работе приложения. Оказалось, что для нормальной работы необходимо установить пакет для ведения логов. Если вы не устанавливали webapp, то можете установить логгер с помощью команды:

composer require logger

Скрипт спросит что необходимо установить, либо будет установлен symfony/monolog-bundle

Я предпочитаю для хранения лога использовать journald. Для этого необходимо внести изменения в настройки логов, например, только для конфигурации dev в файле config/packages/monolog.yaml:

when@dev:
  monolog:
    handlers:
      main:
        type: syslog
        ident: shcc
        level: debug
        channels: ["!event"]

Использование шаблонов для генерации кода

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

composer require --dev symfony/maker-bundle

Она устанавливается в dev секцию, т.к. на сервере необходимости в ней не будет. Она позволяет, например, создавать контроллеры, сущности и др. При создании сущностей БД, кроме самой сущности, будет создан соответствующий репозиторий. После его установки можно пользоваться командами: bin/console make:*.

Создание контроллера

Контроллеры обычно располагаются в каталоге src/Controller. Создать новы контроллер можно с помощью команды:

bin/console make:controller

Можно сразу добавить имя контроллера, например, Index. При этом будет создан класс IndexController. Внутри него можно увидеть единственный метод index:

class IndexController extends AbstractController
{
    #[Route('/index', name: 'app_index')]
    public function index(): JsonResponse
    {
        return $this->json([
            'message' => 'Welcome to your new controller!',
            'path' => 'src/Controller/IndexController.php',
        ]);
    }
}

Современные версии Symfony используют атрибуты. Здесь можно увидеть атрибут Route, который описывает при каких условиях будет вызываться данный метод. Основным параметром является параметр path — путь, который обрабатывает этот метод. Параметр name указывает имя, по которому можно в коде и шаблонах ссылаться на этот путь. Также, при желании можно указать какой тип запроса будет обрабатывать метод: GET, POST, PATCH и др. В конце метод должен вернуть Response, или, в данном случае, его разновидность, JsonResponse.

Использование баз данных

Подробности по использованию Doctrine можно найти на [официальном сайте Symfony[(https://symfony.com/doc/current/doctrine.html).

Установим пакет, который подключил все необходимые для работы Doctrine ORM компоненты, в том числе для работы с миграциями.

composer require symfony/orm-pack

Чтобы работала генерация кода, необходимо установить, если вы его ещё не устанавливали.

composer require --dev symfony/maker-bundle

Создать новую сущность БД можно с помощью

bin/console make:entity

При необходимости можно сразу указать имя класса. Созданный класс, который описывает сущность появится по стандартному пути src/Entity.

После создания сущностей можно создать миграцию:

bin/console make:migration

Файл миграции появится в пути migrations в корне проекта. Запуск миграции:

bin/console doctrine:migrations:migrate

При этом будут выполнены все миграции, имена которых отсутствуют в таблице БД doctrine_migration_versions.

Пакет который добавляет поддержку типов PostgreSQL в проект:

composer require opensoft/doctrine-postgres-types

После установки необходимые типы должны быть прописаны в config/packages/doctrine.yaml. Читайте файл документации в репозитории. На момент написания этой заметки предлагали следующую конфигурацию:

doctrine:
  dbal:
    types:
      text_array: "Doctrine\\DBAL\\PostgresTypes\\TextArrayType"
      int_array: "Doctrine\\DBAL\\PostgresTypes\\IntArrayType"
      ts_vector: "Doctrine\\DBAL\\PostgresTypes\\TsvectorType"
      ts_query: "Doctrine\\DBAL\\PostgresTypes\\TsqueryType"
      xml: "Doctrine\\DBAL\\PostgresTypes\\XmlType"
      inet: "Doctrine\\DBAL\\PostgresTypes\\InetType"
    mapping_types:
      _text: text_array
      _int4: int_array
      tsvector: ts_vector
      tsquery: ts_query
      xml: xml
      inet: inet

Профилировщик

Получать детальную информацию о том как работает ваш сайт можно с помощью установки профилировщика

composer require --dev symfony/profiler-pack

После его установки на dev машине внизу сайта появился строка, где вы можете просмотреть множество информации о работе вашего сайта. Например, можно просмотреть какие запросы к БД использовались или какой пользователь в настоящее время находится на сайте, и множество другого.

Настройка входа на сайт

Настройка входа на сайт довольно сложная. Из документации рекомендую почитать следующее:

  1. Настройка входа на сайт с помощью стандартного механизма сессий PHP
  2. Долговременные сессии с помощью cookie. Необходимы для того, чтобы при истечении стандартной сессии PHP пользователь мог перелогиниваться автоматически.
  3. Дополнительный тюнинг сессий пользователей.

Использование JavaScript

При необходимости в проект можно добавить сборку кода на JavaScript и CSS с помощью Webpack:

composer require symfony/webpack-encore-bundle
npm install

Далее можно, например, подключить Boostrap и сборку CSS из SASS/SCSS:

npm install bootstrap --save-dev
npm install sass-loader@^13.0.0 sass --save-dev

Кроме всего, Symfony легко интегрирует фреймворки JavaScript, такие как Vue, React и др.

Тестирование проекта

Для тестирования проекта можно использовать PHPUnit. Если вы хотите проводить функциональное тестирование (когда производятся запросы на веб-сервер и анализируются его ответы), то можете дополнительно установить browser-kit:

composer require phpunit/phpunit --dev
composer require symfony/browser-kit --dev

Заключение

В этом небольшом обзоре описаны шаги по созданию своего первого приложения на Symfony. Заметка создана скорее с целью сохранить сборник рецептов для создания нового проекта. Но я буду рад если эта заметка показалась вам интересной и полезной.


Обратите внимание, что заметки могут обновляться со временем. Это может быть как исправление найденных ошибок, так и доработка содержания с целью более полного раскрытия темы. Информация об изменениях доступна в репозитории на github. Там же вы можете оставить в Issue ваши замечания по данной заметке.


Если данная заметка оказалась вам полезной, можете поблагодарить автора финансово.