kunstmaan/fixtures-bundle
KunstmaanFixturesBundle adds flexible fixture loading to Symfony apps, letting you define test and demo data in YAML and load it via console commands, with support for ordering, dependencies, and clean database seeding.
This bundle lets you declare Doctrine fixtures in YAML instead of PHP, with named fixtures, Faker-style value expressions, and cross-references between fixtures. It comes out of the Kunstmaan CMS ecosystem and is best treated as a small, single-purpose tool: it parses YAML, instantiates entities, hydrates properties, and persists them.
Minimal setup:
composer require kunstmaan/fixtures-bundle (pin the version — see Gotchas).Kunstmaan\FixturesBundle\KunstmaanFixturesBundle in config/bundles.php (or AppKernel).app/Resources/fixtures/fixtures.yml or src/DataFixtures/fixtures.yml. Confirm the exact expected paths and root keys against the bundle's README and DependencyInjection/Configuration.php in the repo — the docs are thin, and the config tree is the source of truth.bin/console list fixtures for the exact name) against your dev or test database.First use case: take the entities you currently seed by hand in PHP (users, categories, a handful of content pages) and move them into one YAML file. The win is that non-PHP-shaped data (lists of names, slugs, locale variants) becomes editable without touching code, and relationships can be declared by name instead of resolved in PHP.
Where to look first in the repo:
Builder/ and Parser/ — how YAML becomes a Fixture object.Fixture/ — the value object holding entity class, name, properties, dependencies, order.Provider/ — where Faker-style expressions are resolved; the place to hook custom values.Command/ — the load command, its options, and how it interacts with the EntityManager.One file per domain, not one giant file. Split fixtures/users.yml, fixtures/taxonomy.yml, fixtures/content.yml. Loading order between files is easier to reason about than ordering inside a 500-line YAML.
Root key = entity class, children = named fixtures. The typical shape is:
App\Entity\Category:
cat_news:
name: News
slug: news
cat_blog:
name: Blog
slug: blog
App\Entity\Post:
post_hello:
title: '<sentence(4)>'
body: '<paragraphs(3)>'
category: '@cat_news'
publishedAt: '<dateTimeBetween("-1 year", "now")>'
Names (cat_news, post_hello) are your reference handle; @cat_news resolves to the persisted entity. Verify the reference sigil (@) against the README — reference syntax is the one thing you do not want to guess.
Let the bundle handle association wiring. Prefer @name references over hard-coded IDs. This is the main reason to use the bundle instead of plain Doctrine fixtures: the dependency graph is derived from references, so you can add a fixture without renumbering anything.
Use explicit dependencies/order where the graph isn't obvious. If a fixture does not reference another but still needs it persisted first (e.g. a join row, a translation row), declare the dependency rather than relying on file order. File order is fragile once you split files.
Sequences for unique columns. Emails, slugs, and usernames need uniqueness across runs and within a run. Use the bundle's sequence/unique mechanism (or a Faker unique() expression) rather than '<email()>', which will collide at a few hundred rows.
Seed dev and test through the same YAML. Point both environments at the same fixture directory and let the database name differ. Test suites then get a deterministic baseline; keep a small fixtures/test/*.yml overlay for cases where production-shaped data is too heavy for CI.
Custom providers for domain values. Anything you can't express with Faker — a valid enum, a locale-aware slug, a checksummed reference number — belongs in a custom provider registered in the container. That keeps YAML readable and puts the logic under test.
Pair with DoctrineFixturesBundle when you need ordered, code-driven setup. If a step genuinely requires PHP (filesystem assets, service calls, media processing), do it in a Doctrine fixture that runs before the YAML load rather than contorting the YAML.
composer.json constraints against your Symfony and PHP versions before committing — this bundle predates Symfony 5/6 conventions and may not run cleanly on a modern stack.Fixture value object are more reliable than the README. When unsure of a key, dump the parsed fixtures or add a temporary var_dump in the builder rather than guessing.'<sentence(4)>' must be quoted; unquoted < and > will be parsed as YAML structures or silently mangled. Same for anything with : or #.@ to a fixture defined later in the same file) may or may not be supported depending on how the parser sorts. If a load fails on a missing reference, that's usually the cause — reorder or declare a dependency.$em->flush() control.How can I help you explore Laravel packages today?