khepin/yaml-fixtures-bundle
Symfony bundle that loads Doctrine fixtures from YAML, letting you define seed data and entity relationships in readable files instead of PHP. YAML definitions support properties, references, and associations, making fixtures easier to read and maintain than large PHP fixture classes while populatin...
Architecture fit — poor as-is, salvageable as a pattern. Despite the brief framing this as a Laravel package, khepin/yaml-fixtures-bundle is a Symfony2 Bundle: it registers services through the Symfony DI container, depends on symfony/framework-bundle and doctrine/data-fixtures, and exposes a console command in the khepin: namespace. Laravel has no bundle/container-extension concept, so it cannot be installed into a Laravel application without a compatibility shim that is worth more than the functionality it delivers. The genuinely reusable asset is the idea and schema: declarative YAML files describing records plus named references (@user_1) that get resolved into foreign keys and persisted in dependency order. That logic is small — likely a few hundred lines across a YAML parser wrapper, a property mapper, and a reference resolver.
Integration feasibility — moderate, via extraction rather than adoption. The valuable core does not depend on Doctrine specifically; it maps scalar keys to entity properties and resolves references. A port to Eloquent models or to DB::table() inserts is realistic, provided we accept that the mapping layer must be rewritten (Doctrine metadata → Eloquent attributes/casts). Dependency-wise, symfony/yaml remains actively maintained as a standalone component and can be pulled without the framework bundle, so we can keep the file format and drop the baggage.
Technical risk — high, concentrated in lifecycle and security hygiene.
symfony/yaml releases permitted object instantiation and !php/object-style tags; even though fixtures are developer-authored, importing that parser at an unpinned version is an avoidable deserialization surface.Key questions for the requesting team
Stack fit — do not install the bundle. Treat this as a reference implementation. The only artefacts worth carrying forward are the YAML document schema (entities as top-level keys, records as list items, @name references) and the ordered-persistence algorithm.
Migration path
App\Support\Fixtures) and delete all Symfony DI, bundle class, and command wiring.symfony/yaml:^6.x||^7.x used standalone, and explicitly disable object parsing (Yaml::PARSE_OBJECT is opt-in, so keep it off).Model::create() or bulk insert() per collection, with casts handling the type coercion the old Doctrine mapper did implicitly.php artisan fixtures:load {path}) with --class, --truncate, and --dry-run flags — the archived bundle's command options are a reasonable spec to copy.Model::factory() for deep relational graphs.Compatibility
symfony/yaml and the framework itself, so future Laravel majors are a low-cost re-verification.Sequencing
Maintenance — low effort, permanent ownership. Upstream is archived and will never move; there is no upgrade treadmill, but also no fixes. Realistically the port is a 300–800 LOC internal utility that one engineer can own. The hidden cost is not code maintenance but convention maintenance: every model change is a potential fixture-schema drift, and someone must own the lint/validation step or the fixtures silently rot.
Support — no external escalation path. There is no maintainer, no issue tracker with responses, and no vendor. Any defect is ours. Mitigate with an internal README covering the schema, the reference syntax, and the ordering rules, plus tests that exercise a fixture set against the real schema so drift fails CI rather than a demo.
Scaling — effectively unconstrained for its purpose. Fixture loading is a development, test, and demo-provisioning activity, not a production hot path. Reference resolution is typically one or two passes over the parsed document; performance only becomes a concern in the tens-of-thousands-of-records range, where bulk inserts and chunking solve it. Memory is bounded by the largest YAML file. The real scaling limit is human: YAML fixtures become harder to navigate than factories past a few dozen models, which argues for scoping this to seed/demo data, not the primary test-data strategy.
Failure modes to design against
yes/no/on/off and date-like strings becoming booleans and timestamps. Fix with strict parsing plus a lint rule.@name and circular FKs. Fail loudly with the offending reference, and support a deferred second-pass update for cyclic relations.symfony/yaml on modern PHP is the most plausible way this bites us; the standalone modern component avoids it entirely.Model::factory() first. If the YAML path is not clearly better for relational graphs, adoption will be zero and the port wasted.Ramp-up — moderate, and mostly conceptual. The YAML vocabulary is learnable in under an hour, but it is a foreign convention in a Laravel codebase: new hires know factories, not fixture bundles, so expect documentation to carry the onboarding load. Plan for one internal brown-bag and a worked example fixture set. If the team cannot articulate why YAML beats factories after the pilot, the correct TPM recommendation is to stop at the spike, keep the reference-resolver idea as inspiration, and build the seeding logic natively on Eloquent.
How can I help you explore Laravel packages today?