Symfony
Данная заметка создана скорее для себя. Я не являюсь опытным разработчиком на 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.4
— PHP 8.1
, а для 7.0
— PHP 8.2
. Если не использовать контейнеры, а пользоваться обычной виртуальной машиной на Ubuntu, то версию PHP 8.2
до выхода Ubuntu 24.04 LTS будет затруднительно. Точнее потребуется подключать сторонние репозитории, что не очень удобно и безопасно.
Таким образом при выборе версии фреймворка лучше руководствоваться следующими принципами:
- выбирать самую новую версию фреймворка;
- убедиться, что эта версия способна работать на вашем сервере, т.е. поддерживает ли он необходимую версию PHP.
Как вы видите, те, кто пользуется контейнерами в плюсе. Они всегда могут использовать последнюю актуальную версию фреймворка.
С другой стороны, вы можете совершенно безболезненно перейти с версии 6.4
на 7.0
, если ваш код не выдаёт никаких предупреждений об устаревании. Однако при обновлении с версии 6.0
до 7.0
могу возникнуть проблемы. Необходимо обновиться предварительно до версии 6.4
, проверить что вашем коде устарело, исправить это и, уже потом, переходить на 7.0
.
Создание проекта
Для старта нового проекта достаточно загрузить готовый скелет приложения c помощью composer, с нужной версией фреймворка, например:
composer create-project symfony/skeleton:"7.0.*" ИМЯ_ПРОЕКТА
Новый проект будет состоять из нескольких каталогов и файлов. Каталоги:
- bin — набор исполняемых файлов. Изначально есть только один
bin/console
. Через него можно выполнять запуск служебных утилит, а также собственного кода, который оформлен соответствующим образом. - config — набор файлов конфигурации.
- public — каталог, который должен быть опубликован на вашем веб-сервер, доступный публично. Изначально там только один файл index.php, который используется для обработки запросов. Но туда можно поместить все необходимые вам файлы.
- src — папка с классами вашего приложения. Все ваши классы будут расположены в пространстве имён
App
. Это можно изменить в соответствующих с настройках в composer.json. - var — папка со служебными файлами. Например, там располагаются файлы логов и кэш приложения. Обязательно необходимо сделать эту папку доступной для записи, иначе ваше приложение не сможет нормально работать.
- vendor — стандартный каталог с содержимым подключенных через composer к проекту пакетов.
Файлы:
- .env — файл с переменными окружения. Кроме этого файла в проекте может быть создано несколько аналогичных файлов.
- .gitignore — стандартный файл для системы контроля версий git, который указывает какие файл и каталоги не следует добавлять в репозиторий (например, vendor и var, а также другие).
- composer.json — конфигурация composer.
- composer.lock — специальный файл, который позволяет с помощью composer install полностью воспроизвести конфигурацию проекта, которая была создана на другой машине.
- symfony.lock — служебный файл Symfony.
Ставим разом всё необходимое для веб-приложения
Можно установить множество полезных пакетов для веб-приложения одной командой
composer require webapp
Будут установлены, например:
- symfony/monolog-bundle
- symfony/security-bundle
- symfony/twig-bundle
- phpunit/phpunit
- symfony/maker-bundle
- symfony/web-profiler-bundle
и множество других.
Файлы конфигурации
Файлы конфигурации 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
Настройка входа на сайт
Настройка входа на сайт довольно сложная. Из документации рекомендую почитать следующее:
- Настройка входа на сайт с помощью стандартного механизма сессий PHP
- Долговременные сессии с помощью cookie. Необходимы для того, чтобы при истечении стандартной сессии PHP пользователь мог перелогиниваться автоматически.
- Дополнительный тюнинг сессий пользователей.
Использование 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: The Fast Track.
Профилировщик
Получать детальную информацию о том как работает ваш сайт можно с помощью установки профилировщика
composer require --dev symfony/profiler-pack
После его установки на dev машине внизу сайта появился строка, где вы можете просмотреть множество информации о работе вашего сайта. Например, можно просмотреть какие запросы к БД использовались или какой пользователь в настоящее время находится на сайте, и множество другого.
Настройка IDE
В локальном окружении разработки при генерации исключения Symfony отображает страницу с сообщением исключения и его трассировкой. К отображаемому пути файла в трассировке добавляется ссылка, кликнув на которую можно открыть файл на нужной строке прямо в вашей IDE. Но чтобы воспользоваться этой возможностью, сначала вам нужно настроить IDE. Symfony поддерживает множество разных IDE; я использую Visual Studio Code для данного проекта:
xdebug.file_link_format=vscode://file/%f:%l
Данную строку необходимо добавить в конфигурацию xdebug
. Например, в Fedora, это раздел настраивается с помощью /etc/php.d/15-debug.ini
. В файле есть подобные описание как правильно настроить этот параметр.
Заключение
В этом небольшом обзоре описаны шаги и полезные настройки при создании своего первого проекта на Symfony. Заметка создана скорее с целью сохранить сборник рецептов для создания нового проекта. Но я буду рад если эта заметка показалась вам интересной и полезной.
Обратите внимание, что заметки могут обновляться со временем. Это может быть как исправление найденных ошибок, так и доработка содержания с целью более полного раскрытия темы. Информация об изменениях доступна в репозитории на github. Там же вы можете оставить в Issue ваши замечания по данной заметке.
Если данная заметка оказалась вам полезной, можете поблагодарить автора финансово.