Тестовые данные
Пустой сайт неудобно разрабатывать: не видно, как выглядит список из ста статей или длинный заголовок. Фикстуры — классы, которые заполняют базу тестовыми данными одной командой. У каждого разработчика получается одинаковый набор.
Установка
composer require --dev orm-fixturesПервая фикстура
php bin/console make:fixtures PostFixtures// src/DataFixtures/PostFixtures.php
namespace App\DataFixtures;
use App\Entity\Post;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
class PostFixtures extends Fixture
{
public function load(ObjectManager $manager): void
{
for ($i = 1; $i <= 20; $i++) {
$post = new Post();
$post->setTitle("Статья №$i");
$post->setBody('Текст статьи.');
$post->setPublished($i % 3 !== 0);
$manager->persist($post);
}
$manager->flush();
}
}Загрузка
php bin/console doctrine:fixtures:loadКоманда очищает базу и выполняет все фикстуры.
Правдоподобные данные
Библиотека Faker придумывает имена, адреса, тексты:
composer require --dev fakerphp/fakeruse Faker\Factory;
public function load(ObjectManager $manager): void
{
$faker = Factory::create('ru_RU');
for ($i = 0; $i < 20; $i++) {
$post = new Post();
$post->setTitle($faker->sentence(6));
$post->setBody($faker->paragraphs(3, true));
$manager->persist($post);
}
$manager->flush();
}Связи между фикстурами
Статье нужен автор, созданный в другой фикстуре. Объект запоминают под именем:
// UserFixtures
$this->addReference('user-anna', $user);// PostFixtures
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
class PostFixtures extends Fixture implements DependentFixtureInterface
{
public function load(ObjectManager $manager): void
{
$post = new Post();
$post->setAuthor($this->getReference('user-anna', User::class));
// …
}
public function getDependencies(): array
{
return [UserFixtures::class];
}
}getDependencies() сообщает, какие фикстуры выполнить раньше.
Пароли в фикстурах
Фикстура — сервис, поэтому получает зависимости через конструктор:
public function __construct(private UserPasswordHasherInterface $hasher) {}
public function load(ObjectManager $manager): void
{
$user = new User();
$user->setEmail('admin@example.com');
$user->setPassword($this->hasher->hashPassword($user, 'password'));
$user->setRoles(['ROLE_ADMIN']);
$manager->persist($user);
$manager->flush();
}Частая ошибка
doctrine:fixtures:load удаляет все данные из базы перед загрузкой. Запущенная на рабочем сервере, команда уничтожит настоящие записи. Пакет ставят с ключом --dev, чтобы на сервере его просто не было. Если нужно только добавить данные, используйте ключ --append.