Symfony 3.4: создание бандла, модели и таблицы в БД

Для того, чтобы создать какое-то минимально вменяемое приложение на Symfony нужно сгенерировать несколько сущностей. Все примеры команд будут рассмотрены для версии 3.4. Для начала нужно сгенерирвовать бандл, фактически это пакет для Symfony, в котором могут содержаться все компоненты приложения, либо какие-то его части.

Генерация нового бандла в Symfony 3.4

php bin/console generate:bundle

После чего в интерактивном режиме нужно ввести название бандла, директорию в которой будет создан бандл (можно оставить значение по-умолчанию) а также формат конфигурационных файлов (например, php или yml). В примерах данной статьи я буду использовать название PaymentsBundle.

Также можно предопределить некоторые значения:

php bin/console generate:bundle --namespace=PaymentsBundle --format=yml

Скрипт сгенерирует все необходимые файлы и в конце попросит:

The command was not able to configure everything automatically.
You'll need to make the following changes manually.
- Edit the composer.json file and register the bundle namespace in the "autoload" section:

Далее в файл composer.json нужно добавить либо отредактировать уже имеющиеся строки:

"autoload": {
        "psr-4": {
            "PaymentsBundle\\": "src/PaymentsBundle"
        },
    },

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

composer dumpautoload

Генерация модели

php bin/console doctrine:generate:entity
The Entity shortcut name: PaymentsBundle:Invoice

Также можно сразу задать имя для модели:

php .\bin\console doctrine:generate:entity PaymentsBundle:Crypto

Если сущность с таким именем уже существует в данном бандле, то появится ошибка:

Entity "PaymentsBundle:Invoice" already exists.

Нужно удалить файлы Entity/Invoice.php и Resources/config/doctrine/Invoice.orm.yml.

После заполнения информации о модели будут созданы три файла:

> Generating entity class src\PaymentsBundle\Entity\Invoice.php: OK!
> Generating repository class src\PaymentsBundle\Repository\InvoiceRepository.php: OK!
> Generating mapping file src\PaymentsBundle\Resources\config\doctrine\Invoice.orm.yml: OK!

Если после генерации нужно изменить структуру сущности, например добавить или убрать поля, то нужно вручную отредактировать файл Invoice.orm.yml, после чего запустить команду:

php bin/console doctrine:generate:entities PaymentsBundle

Также можно добавить опцию —no-backup, чтобы не создавались бэкап версии сущностей. Вы же пользуетесь системами контроля версий?

Новые поля будут добавлены в сущности, однако вы получите предупреждение:

NOTE: The doctrine:generate:entities command has been deprecated.
To read more about the differences between anemic and rich models go here http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/getting-started.html#adding-behavior-to-entities.
If you wish to generate your entities, use make:entity --regenerate from MakerBundle instead.

Т.е. предлагают установить бандл с командами для генерации сущностей. Но это не обязательно и возможно будет даже менее удобно.

composer require symfony/maker-bundle --dev

Затем в файл app\AppKernel.php добавить строку:

$bundles[] = new Symfony\Bundle\MakerBundle\MakerBundle();

И проверяем новый генератор:

php bin/console make:entity --regenerate --overwrite PaymentsBundle

Подробнее о генерации сущностей, а также о философии работы с сущностями.

Генерация и обновление таблиц в БД

Отлично сущности созданы, теперь было бы неплохо создать таблицы в базе данных. Для этого воспользуемся командой:

php bin/console doctrine:schema:update --force

Флаг force нужен для принудительного выполнения ALTER запросов в production среде.

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

Возможные ошибки

Например, можно получить такое сообщение об ошибке:

No mapping found for field 'invoice' on class 'PaymentsBundle\\Entity\\Redirect'.

Что делать? Проверьте определение связей, возможно вы написали OneToOne вместо oneToOne, или типа того. Обратите внимание, регистр важен!