doyo/alice-bundle
Symfony bundle that integrates Nelmio Alice with Doctrine to load realistic fixtures from YAML/PHP files. It provides configuration, fixture loading services, and Faker-powered data generation for faster database seeding in Symfony applications.
Install the full stack, not just the bundle. The bundle only wires Alice into Symfony's container — it depends on nelmio/alice, fakerphp/faker, a Doctrine ObjectManager, and the fixtures loader command:
composer require --dev doyo/alice-bundle doctrine/doctrine-fixtures-bundle doctrine/orm
Expect composer to fight you. Verify immediately that php, symfony/*, doctrine/*, nelmio/alice, and the Faker constraint resolve on your runtime before writing any fixture code. This audit is the real first step — most evaluations terminate here.
Register the bundle and configure a fixtures path. Without a Flex recipe you register manually, then add a config file:
// config/bundles.php
return [
// ...
Doyo\AliceBundle\DoyoAliceBundle::class => ['dev' => true, 'test' => true],
];
# config/packages/dev/alice.yaml
alice:
fixtures_path: '%kernel.project_dir%/fixtures'
root_dirs:
- '%kernel.project_dir%'
Where to look first, in order: (a) the package composer.json — the PHP/Symfony/Doctrine/Faker constraints tell you more than the docs do; (b) DoyoAliceBundle::class and its DependencyInjection/*Extension; (c) the console command classes, found via bin/console list | grep -E 'fixtures|alice'. Because this is a fork with sparse documentation, the command surface and the DI extension are the documentation.
Confirm the command you actually have. Variants of this lineage expose doctrine:fixtures:load with an added --fixtures= option, and sometimes a standalone alice:fixtures:load. Run --help on it and note the flags for --fixtures, --group, --append, and --env — the loader's behavior depends heavily on these.
First use case: a single relational graph. Define User with several Post children using named references and Faker, load it, and confirm associations resolve. If a User-hasMany-Post graph works end to end, the bundle is viable for your schema; if it doesn't, stop.
Named references are the core idiom. The whole point of Alice over hand-written seeders is building an object graph declaratively, then referencing pieces of it:
App\Entity\User:
user_{1..10}:
email: '<email()>'
plainPassword: 'secret'
roles: ['<randomElement(["ROLE_USER"])>']
App\Entity\Post:
post_{1..50}:
title: '<sentence()>'
body: '<paragraph(3)>'
author: '@user_*'
The @user_* wildcard distributes posts across all generated users; @user_1 targets one. Use the <...> Faker tag for scalars and @... for object references — mixing them up is the most common authoring error.
Group fixtures by scenario, not by entity. Put shared base fixtures behind one group (e.g. base), then layer scenario groups (demo, load-test, edge-cases). This lets CI load a minimal set, staging load a demo set, and load tests pull a high-volume set from the same files:
App\Entity\Order:
order_{1..500}:
# group: load-test
Load with --group=base --group=load-test.
Wire it into the test bootstrap, not application runtime. For the Symfony path, hook fixture loading into PHPUnit/Paratest's database reset phase rather than the app kernel. Keep the bundle in the test and dev environments only. This is the single discipline that most protects you from the "we seeded production" failure mode.
Use PHP fixtures when YAML hits its ceiling. Alice supports .php fixture files that return arrays. Use them when you need conditional logic, loops over enums, or computed values that would be ugly in the YAML DSL. Keep them dumb — a return array — rather than doing real work in the fixture file.
Leverage service references for real dependencies. Rather than hardcoding a password hash, reference the real service so the fixture matches production behavior:
App\Entity\User:
user_admin:
plainPassword: 'admin'
_serviceRef: '@security.password_hasher' # syntax varies by version
Verify against the upstream nelmio/alice docs, since the service-reference syntax differs across Alice major versions — this is a common source of silent no-ops.
Custom Faker providers for domain-specific data. If you have domain values (e.g. valid SKUs, status codes) Faker doesn't ship, register a custom Faker provider as a service and reference it in fixtures. This is the main extension point that survives the bundle's abandonment risk, because it lives in your code, not the dependency.
Parallel test safety is a design decision, not a config toggle. Paratest with shared fixtures will collide on IDs and sequences. Use per-worker database names and, if you rely on Faker for deterministic data, seed Faker explicitly. Alice's fixture loading is CPU- and memory-bound, so keep the test group small and the load-test group out of CI.
The vendor/repo mismatch is a red flag, not a detail. doyo/alice-bundle pointing at kilip/alice-bundle with zero stars and zero dependents is the classic stale-fork signature. Assume no upstream fixes, pin the version in composer.json, and budget for owning a fork before committing to it.
Faker drift will bite you. Packages of this vintage often depend on the abandoned fzaninotto/faker rather than fakerphp/faker. If you see the former in composer.lock, expect either a constraint override or a fork. Confirm which Faker API surface your fixture tags target — method signatures differ across the transition.
The Doctrine ObjectManager is non-negotiable. Alice's persister expects a Doctrine ObjectManager. This is why the bundle is a non-starter on bare Laravel: Eloquent models expose no Doctrine metadata. If you're determined to run the Alice DSL on Laravel, you write a custom persister and a custom Artisan command — at which point native factories are almost certainly cheaper. Treat that adapter as a scoped project, not a dependency.
Fixture load order and relation dependencies are implicit. Alice resolves named references lazily, but if your fixtures reference an entity that isn't defined (typo in a reference name, wrong group selected), you get a vague error at load time. Debug by narrowing to one fixture file with --fixtures= and verbose output.
--append versus purge changes your test safety story. The default fixture-load behavior purges the target tables. If you're running against a shared or staging database, know exactly which flag you're defaulting to. In tests, combine with transactions or per-test truncation so a failed load doesn't leave dirty state for the next run.
YAML escaping is subtle. Backslashes in regex/date formats, <number> tag nesting, and @ at the start of a string (Alice interprets it as a reference) all need quoting. Wrap Faker tags in single quotes ('<email()>') and escape literal @ when it isn't a reference. Silent misinterpretation here produces plausible-but-wrong data, which is worse than a crash.
Service references require public services in modern Symfony. If you're on Symfony 4.1+ with private-by-default services, referencing a service in a fixture can fail or resolve to an empty value. Mark the specific services you reference as public in services.yaml, and add a test asserting the reference resolves to the expected value.
Debug with dry runs and narrow scopes. Before a full load, run against a single fixture file with --fixtures= and check the SQL Doctrine emits (SQL logger or --verbose). If associations come back empty rather than failing loudly, it's almost always a mapping/ownership-side issue in the Doctrine entity, not an Alice bug — isolate the entity and test its mapping independently.
Extension points to lean on if you fork. The things you're most likely to need to own are: a custom Faker provider (safe, lives in your code), a custom persister (only if you leave Doctrine), and the console command wiring (if you need --group behavior the fork doesn't provide). Everything else — YAML parsing, reference resolution — is upstream nelmio/alice and shouldn't need patching for Symfony-version compatibility alone.
Know the exit ramp. If the composer audit or a two-week spike shows the bundle can't reach current Symfony/PHP, the answer is to vendor nelmio/alice directly (without the bundle) plus hautelook/alice-bundle — the maintained integration — or to abandon Alice entirely for native Doctrine fixtures. Document the rollback (delete fixtures, revert composer.json) before you start, so evaluating it stays a decision rather than a commitment.
How can I help you explore Laravel packages today?