Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Data Fixtures Laravel Package

doctrine/data-fixtures

Doctrine Data Fixtures provides a simple way to define, manage, and execute fixture classes for loading sample or test data into Doctrine ORM or ODM. Useful for seeding databases, repeatable test setups, and development environments with consistent data.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup in Laravel

  1. Install the package:

    composer require doctrine/data-fixtures
    
  2. Create a fixture class (e.g., database/fixtures/UserFixture.php):

    namespace Database\Fixtures;
    
    use Doctrine\Bundle\FixturesBundle\Fixture;
    use Doctrine\Persistence\ObjectManager;
    use App\Models\User;
    
    class UserFixture extends Fixture
    {
        public function load(ObjectManager $manager)
        {
            $user = new User();
            $user->name = 'John Doe';
            $user->email = 'john@example.com';
            $manager->persist($user);
            $this->addReference('user', $user); // Reference for later use
            $manager->flush();
        }
    }
    
  3. Run fixtures via Artisan:

    php artisan doctrine:fixtures:load
    

    (Note: Requires doctrine/doctrine-bundle for Laravel integration. See below for setup.)


First Use Case: Seeding Development Data

  • Use UserFixture to populate a users table with test data.
  • Reference the created user in another fixture (e.g., PostFixture):
    $post = new Post();
    $post->title = 'Hello World';
    $post->user = $this->getReference('user'); // Reuse the referenced user
    

Implementation Patterns

1. Laravel Integration

Using doctrine/doctrine-bundle (Recommended)

  1. Install the bundle:
    composer require doctrine/doctrine-bundle
    
  2. Publish config:
    php artisan vendor:publish --provider="Doctrine\Bundle\DoctrineBundle\DoctrineBundle" --tag="orm_mapping"
    
  3. Configure config/packages/doctrine.yaml to enable fixtures:
    doctrine:
        orm:
            auto_generate_proxy_classes: true
            mappings:
                App:
                    is_bundle: false
                    type: attribute
                    dir: "%kernel.project_dir%/src/Entity"
                    prefix: "App\Entity"
                    alias: App
    
  4. Create a custom Artisan command (optional) to load fixtures:
    // app/Console/Commands/LoadFixtures.php
    namespace App\Console\Commands;
    
    use Doctrine\Bundle\FixturesBundle\Command\LoadDataFixturesDoctrineCommand;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Output\OutputInterface;
    
    class LoadFixtures extends LoadDataFixturesDoctrineCommand
    {
        protected function getFixturesDir(): string
        {
            return __DIR__ . '/../../database/fixtures';
        }
    }
    
    Register the command in app/Console/Kernel.php:
    protected $commands = [
        Commands\LoadFixtures::class,
    ];
    

2. Workflow: Fixture Development

  1. Create Fixtures:

    • Organize fixtures by feature (e.g., UserFixture, RoleFixture, PermissionFixture).
    • Use addReference() to link entities across fixtures.
  2. Load Fixtures:

    php artisan doctrine:fixtures:load
    
    • Load specific fixtures:
      php artisan doctrine:fixtures:load --fixtures=UserFixture
      
  3. Order Dependencies:

    • Implement OrderedFixtureInterface to control load order:
      use Doctrine\Bundle\FixturesBundle\Fixture\LoadedFixtureInterface;
      
      class UserFixture extends Fixture implements OrderedFixtureInterface
      {
          public function getOrder(): int
          {
              return 1; // Load before RoleFixture (order = 2)
          }
      }
      
  4. Purge Data Before Loading:

    • Use the ORMExecutor with purging:
      php artisan doctrine:fixtures:load --purge-with-truncate
      
    • Or configure in config/packages/doctrine.yaml:
      doctrine:
          orm:
              auto_generate_proxy_classes: true
              fixtures:
                  purge_mode: 'truncate' # or 'delete'
      

3. Advanced Patterns

Dependency Injection in Fixtures

Inject services (e.g., Hasher, Mailer) into fixtures:

use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class UserFixture extends Fixture implements ContainerAwareInterface
{
    private ContainerInterface $container;

    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }

    public function load(ObjectManager $manager)
    {
        $hasher = $this->container->get('hasher');
        $user = new User();
        $user->password = $hasher->hash('password123');
        $manager->persist($user);
    }
}

Parameterized Fixtures

Use Laravel’s config or environment variables:

public function load(ObjectManager $manager)
{
    $adminEmail = config('fixtures.admin_email');
    $admin = new User(['email' => $adminEmail, 'role' => 'admin']);
    $manager->persist($admin);
}

Dry Run Mode

Test fixtures without persisting data:

php artisan doctrine:fixtures:load --dry-run

(Requires DryRunORMExecutor from v2.2.0+.)


Gotchas and Tips

1. Common Pitfalls

Circular References

  • Issue: Fixture A references Fixture B, and Fixture B references Fixture A.
  • Fix: Use getReference() only after the entity is persisted. Avoid bidirectional references in the same fixture.

Purging Data

  • Issue: purge-with-truncate drops constraints/triggers. Use purge-with-delete for safer cleanup.
  • Fix: Configure purging in config/packages/doctrine.yaml:
    doctrine:
        orm:
            fixtures:
                purge_mode: 'delete' # Safer for production-like environments
    

Transaction Rollbacks

  • Issue: Fixtures run in a transaction by default. If an error occurs, all changes roll back.
  • Fix: Disable transactions for critical fixtures:
    $manager->getConnection()->beginTransaction();
    try {
        $this->load($manager);
        $manager->getConnection()->commit();
    } catch (\Exception $e) {
        $manager->getConnection()->rollBack();
        throw $e;
    }
    

2. Debugging Tips

Enable Verbose Logging

Run fixtures with debug output:

php artisan doctrine:fixtures:load -vv

Check Fixture Order

Use getOrder() to debug load sequences:

class UserFixture implements OrderedFixtureInterface
{
    public function getOrder(): int
    {
        return 1; // Lower numbers load first
    }
}

Inspect References

Dump references to verify they’re set correctly:

public function load(ObjectManager $manager)
{
    $user = $this->getReference('user');
    if (!$user) {
        throw new \RuntimeException('User reference not found!');
    }
    dump($user); // Debug output
}

3. Performance Optimization

Batch Inserts

Reduce database round-trips by persisting entities in batches:

public function load(ObjectManager $manager)
{
    $users = [];
    for ($i = 0; $i < 1000; $i++) {
        $users[] = new User(['name' => "User $i"]);
    }
    $manager->persist($users);
    $manager->flush();
}

Disable Events

Skip Doctrine events (e.g., prePersist) for bulk operations:

$manager->getEventManager()->removeAllEventListeners();

4. Extension Points

Custom Executors

Extend ExecutorInterface for custom logic (e.g., logging, validation):

use Doctrine\Common\DataFixtures\Executor\ExecutorInterface;
use Doctrine\Common\DataFixtures\Executor\ORMExecutor;

class LoggingExecutor implements ExecutorInterface
{
    private ORMExecutor $executor;

    public function __construct(ORMExecutor $executor)
    {
        $this->executor = $executor;
    }

    public function execute(ExecutorInterface $fixture, bool $purgeMode = false)
    {
        \Log::info("Loading fixture: " . get_class($fixture));
        return $this->executor->execute($fixture, $purgeMode);
    }
}

Custom Purger

Implement PurgerInterface for database-specific cleanup:

use Doctrine\Common\DataFixtures\Purger\PurgerInterface;

class CustomPurger implements PurgerInterface
{
    public function purge(ObjectManager $manager): void
    {
        $conn = $manager->getConnection();
        $conn->executeStatement('TRUNCATE TABLE users RESTART ID
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai