Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Test data

An empty site is awkward to develop: you cannot see what a list of a hundred posts or a long title looks like. Fixtures are classes that fill the database with sample data in one command. Every developer gets the same set.

Installation

composer require --dev orm-fixtures

The first fixture

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("Post #$i");
            $post->setBody('The text of the post.');
            $post->setPublished($i % 3 !== 0);
 
            $manager->persist($post);
        }
 
        $manager->flush();
    }
}

Loading

php bin/console doctrine:fixtures:load

The command empties the database and runs every fixture.

Realistic data

The Faker library invents names, addresses and texts:

composer require --dev fakerphp/faker
use Faker\Factory;
 
public function load(ObjectManager $manager): void
{
    $faker = Factory::create();
 
    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();
}

References between fixtures

A post needs an author created in another fixture. The object is remembered under a name:

// 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() tells which fixtures to run first.

Passwords in fixtures

A fixture is a service, so it receives dependencies through its constructor:

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();
}

Common mistake

doctrine:fixtures:load deletes all data from the database before loading. Run on a production server, the command destroys real records. The package is installed with the --dev flag so that it simply does not exist on the server. If you only need to add data, use the --append flag.

Thanks for reading!

Donate to the site — we work hard for you.