Weave 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

Symfony Dto Laravel Package

php-collective/symfony-dto

php-collective/symfony-dto brings typed DTOs to Symfony controllers, letting you map and validate request data into dedicated objects instead of raw arrays. It keeps request handling explicit, type-safe, and easier to maintain, with attribute-driven mapping and validation.

View on GitHub
Deep Wiki
Context7

Getting Started

php-collective/symfony-dto is a DTO-generation package that reads a config definition and emits PHP DTO classes. Despite the "symfony" in the name, the workflow maps cleanly onto a Laravel app: install with Composer, publish the config, define your DTOs, generate, and commit.

  1. Install and publish
    composer require php-collective/symfony-dto
    php artisan vendor:publish --tag=dto-config   # tag may differ; check the README
    
  2. Look here first: the published config file and the package README's config reference. As of 0.1.4, the PHP config file is consistently named dto.php — if you're upgrading from 0.1.3, confirm your published file matches that name (see Gotchas).
  3. First use case: define one small DTO (e.g. an Address or CreateUserInput) in dto.php, run the generation command, and inspect the output class. Once that loop works, scale to the rest of your boundary objects.

Treat the config file as the source of truth, and the generated classes as build artifacts you regenerate — not hand-edit.

Implementation Patterns

Config-driven generation, committed output. Keep dto.php in version control and commit the generated classes too. Reviewers can then see DTO diffs in PRs, and deploys don't depend on a generation step succeeding. Add a CI check that regenerates and fails on a dirty diff — that catches "forgot to regenerate after editing the schema" before it ships.

Wrap the generator in an Artisan command. Even if the package ships its own console command, add a thin app-level command (php artisan app:generate-dtos) so your team has one stable entry point. It also gives you a place to chain post-processing (CS fixing, static analysis) without every developer remembering the flags.

Use DTOs at the boundaries, not in the domain core. The highest-value spots in a Laravel app:

  • Form Request → DTO: validate in the Form Request, then hydrate a DTO via fromArray()/constructor for the controller and service layer.
  • API Resources: accept a DTO rather than an Eloquent model so the response shape doesn't silently drift with schema changes.
  • Job and event payloads: generated DTOs give you a typed, serializable contract for queued work.

Keep serialization explicit. If the package generates fromArray/toArray (or similar), route all hydration through those methods rather than new static(...) with positional args. When a property is added in the next schema change, you have exactly one place to fix.

Integrate with static analysis. Point PHPStan/Larastan at the generated directory and add it to your baseline only if necessary. Generated DTOs with typed properties are cheap wins for catching nullability bugs at the edges of your app.

Regeneration workflow. Schema/config change → regenerate → run the DTO diff through review. If the generated output is noisy (ordering, formatting), normalise it with a post-generation Pint pass so diffs stay readable.

Gotchas and Tips

0.1.4 renames the PHP config file convention. The release makes dto.php the consistent filename for PHP-format config. If you published config under 0.1.3, you may have an orphaned file that the package no longer loads — generation will then silently use defaults or fail with a confusing "no DTOs defined" result. After upgrading, check config/ for a stale file, rename or re-publish, and clear caches.

Config caching will bite you. Laravel caches the merged config array. If dto.php performs any runtime logic (env lookups, closures, base_path() calls), php artisan config:cache in production can freeze stale or null values. Keep the config file a plain array of scalars and paths where possible.

Symfony ancestry means Symfony-shaped docs and errors. Expect bundle-style naming, YAML/XML config examples, and exception messages that reference Symfony concepts. Translate mentally: config/packages/dto.php in the docs is your config/dto.php; bundle registration is your service provider.

Pin the version during 0.x. At 0.1.x the public surface is still moving — a patch release just changed a file-naming convention. Use a caret constraint but watch the changelog on every bump, and run your regeneration CI check immediately after upgrading so drift surfaces in a PR rather than in production.

Generated code is not your code. Don't patch generated DTOs directly; the next run overwrites them. If you need custom behaviour (accessors, validation annotations), check for a stub/template extension point first, and otherwise subclass or wrap the generated class rather than editing it.

Paths and namespaces are the usual first failure. If classes land in the wrong place or use statements don't resolve, it's almost always an output-directory or root-namespace mismatch between dto.php and your composer.json PSR-4 map. Verify with composer dump-autoload before debugging anything deeper.

Debugging a bad generation run: generate into a scratch directory first, diff against the committed output, and only then overwrite. It's much faster than git checkout-ing your way back.

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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console