Databases and the Doctrine
Базы данных и Doctrine ORM
Symfony предоставляет все необходимые инструменты для работы с базами данных в ваших приложениях благодаря Doctrine
Прочтите эту статью, если вам нужен низкоуровневый доступ для выполнения необработанных SQL-запросов к реляционным базам данных (аналогично PDO в PHP)
Установка Doctrine
composer require symfony/orm-pack
composer require --dev symfony/maker-bundle
Информация о подключении к базе данных хранится в переменной среды с именем DATABASE_URL
Создание пользователя и базы данных
#Создать роль в базе данных
CREATE ROLE user1;
#Добавить пароль для пользователя
ALTER ROLE user1 WITH LOGIN PASSWORD 'password';
#Создать базу данных
CREATE DATABASE db1 OWNER user1 ENCODING = 'UTF-8' LC_COLLATE = 'ru_RU.UTF-8' LC_CTYPE = 'ru_RU.UTF-8';
DATABASE_URL="postgresql://user1:password@127.0.0.1:5432/db1?serverVersion=16&charset=utf8"
Если имя пользователя, пароль, имя хоста или базы данных содержат специальные символы, используемые в URI (например, : / ? # [ ] @ ! $ & ' ( ) * + , ; =), их необходимо закодировать. Полный список зарезервированных символов приведен в RFC 3986. Для кодирования можно использовать функцию urlencode или процессор переменных окружения urlencode. В этом случае необходимо удалить префикс resolve: в config/packages/doctrine.yaml, чтобы избежать ошибок: url: '%env(DATABASE_URL)%'
Чтобы избежать проблем с URL-кодированием при использовании специальных символов в учетных данных, можно использовать отдельные параметры подключения вместо формата URL. Определите каждое значение как отдельную переменную среды и заключите его в одинарные кавычки в файле .env, чтобы такие символы, как $ и #, не интерпретировались:
DATABASE_PASSWORD='p@ss$wo#rd'
Затем настройте Doctrine на использование отдельных параметров:
# config/packages/doctrine.yaml
doctrine:
dbal:
user: '%env(DATABASE_USER)%'
password: '%env(DATABASE_PASSWORD)%'
host: '%env(DATABASE_HOST)%'
port: '%env(DATABASE_PORT)%'
dbname: '%env(DATABASE_NAME)%'
driver: pdo_pqsql
Существует множество других команд Doctrine. Запустите php bin/console list doctrine , чтобы увидеть полный список.
Источник: https://symfony.com/doc/current/doctrine.html
Создание класса сущностей
С помощью команды make:entity вы можете создать класс сущности и необходимые поля в интерактивном режиме
php bin/console make:entity
После подтверждения будет создан файл src/Entity/Profile.php
Этот класс называется «сущностью». Теперь можно сохранять объекты Profile и запрашивать их из profile таблицы в своей базе данных. Каждое свойство Product сущности можно сопоставить со столбцом в этой таблице. Обычно это делается с помощью атрибутов — #[ORM\Column(...)] комментариев, которые видно над каждым свойством.
Вы можете передать --with-uuid или --with-ulid в make:entity. Используя компонент Uid Symfony, вы можете создать сущность с типом id как Uuid или Ulid вместо int.
Типы полей сущностей
Ознакомьтесь с перечнем типов сопоставления Doctrine
https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/basic-mapping.html#reference-mapping-types
Один из таких типов основан на перечисляемых типах данных PHP, которые позволяют определить закрытый набор возможных значений для данного типа. Это делает их подходящим решением для моделирования свойств сущностей, которые могут принимать только заранее определенный набор значений.
Подробнее: https://symfony.com/doc/current/doctrine.html#entity-field-types
Миграции: создание таблиц/схемы базы данных
#Для создания миграции
php bin/console make:migration
created: migrations/Version20260507165112.php
Success!
Review the new migration then run it with php bin/console doctrine:migrations:migrate
#Для создания сущности (таблицы) в базе данных
#Выполнить миграцию
php bin/console doctrine:migrations:migrate
WARNING! You are about to execute a migration in database "apimega" that could result in schema changes and data loss. Are you sure you wish to continue? (yes/no) [yes]:
> yes
[notice] Migrating up to DoctrineMigrations\Version20260507165112
[notice] finished in 16.2ms, used 22M memory, 1 migrations executed, 3 sql queries
[OK] Successfully migrated to version: DoctrineMigrations\Version20260507165112
Эта команда запускает все файлы миграции, которые еще не были применены к вашей базе данных. Эту команду следует запускать при развертывании рабочей среды, чтобы поддерживать базу данных в актуальном состоянии.
Миграции и добавление новых полей
Можно отредактировать класс сущности, чтобы добавить новое свойство. Но также можно снова использовать make:entity:
php bin/console make:entity
Class name of the entity to create or update
> Profile
В процессе создания нового свойства, в класс Profile будет добавлено свойство и методы set*() get*()
После редактирования класс необходимо сгенерировать новую миграцию
Система миграции умна. Она сравнивает все ваши сущности с текущим состоянием базы данных и генерирует SQL-запросы, необходимые для их синхронизации
#Создать миграцию
php bin/console make:migration
#Выполнить миграцию
php bin/console doctrine:migrations:migrate
Если вы предпочитаете добавлять новые свойства вручную, команда make:entity может сгенерировать для вас методы получения и установки значений.
php bin/console make:entity --regenerate
Если вы внесли какие-то изменения и хотите перегенерировать все методы получения и установки значений, также передайте --overwrite.
Источник: https://symfony.com/doc/current/doctrine.html#migrations-adding-more-fields
Создание контроллера сущности и сохранение в базе данных
#Создать контроллер
php bin/console make:controller ProfileController
Do you want to generate PHPUnit tests? [Experimental] (yes/no) [no]:
>
created: src/Controller/ProfileController.php
created: templates/profile/index.html.twig
Success!
#src/Controller/ProfileController.php
namespace App\Controller;
use App\Entity\Profile;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
final class ProfileController extends AbstractController
{
#[Route('/profile', name: 'add_profile')]
public function createProfile(EntityManagerInterface $entityManager): Response
{
$profile = new Profile();
$profile->setNameUser('Admin');
$profile->setPasswordUser('password');
//сохранить объект Product (запросы пока не выполняются)
$entityManager->persist($profile);
//фактически выполняет запросы (например, запрос INSERT)
$entityManager->flush();
return new Response($profile->getId());
}
}
Аргумент EntityManagerInterface $entityManager указывает Symfony на необходимость внедрить сервис Entity Manager в метод контроллера. Этот объект отвечает за сохранение объектов в базе данных и их извлечение из нее.
Вызов persist($product) указывает Doctrine на необходимость «управления» объектом
При вызове метода flush() Doctrine просматривает все объекты, которыми она управляет, чтобы определить, нужно ли сохранять их в базе данных. В этом примере данных объекта $profile нет в базе данных, поэтому менеджер сущностей выполняет INSERT запрос, создавая новую строку в таблице profile
Независимо от того, создаете вы объекты или обновляете их, процесс всегда один и тот же: Doctrine достаточно умен, чтобы определить, нужно ли выполнить INSERT или UPDATE для вашего объекта.
После перехода на страницу /profile, будет добавлен пользователь в таблицу базы данных
Проверить наличие данной строки можно с помощью следующей команды
php bin/console dbal:run-sql 'SELECT * FROM profile'






