Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Тестовые данные

Пустой сайт неудобно разрабатывать: не видно, как выглядит список из ста статей или длинный заголовок. Фикстуры — классы, которые заполняют базу тестовыми данными одной командой. У каждого разработчика получается одинаковый набор.

Установка

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/faker
use 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.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.