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-fixturesThe 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:loadThe command empties the database and runs every fixture.
Realistic data
The Faker library invents names, addresses and texts:
composer require --dev fakerphp/fakeruse 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.