- How does `from($data)` work in Laravel with this package? Can I replace manual array mapping in controllers?
- The `from($data)` method uses reflection to hydrate all properties in a single call, replacing repetitive `$object->property = $data['property']` logic. In Laravel, you can use it directly in controllers (e.g., `User::from($request->all())`) or API responses, reducing boilerplate while keeping validation and casting centralized via `#[Describe]` attributes.
- Does this package support Laravel’s validation system (e.g., `Validator::make`)?
- Yes, it integrates with Laravel’s validation by allowing `#[Describe]` attributes to define rules like `required`, `nullable`, or custom casts (e.g., `cast => 'trim'`). You can still use Laravel’s `Validator` alongside it, but DataModel handles the hydration and type safety upfront.
- What Laravel versions and PHP versions are supported?
- The package requires **PHP 8.0+** (for attributes, union types, and named arguments) and is fully compatible with **Laravel 9+**. It leverages modern PHP features but avoids breaking changes, so it works seamlessly with Laravel’s latest conventions.
- How does recursive hydration (e.g., nested objects like `User->Address`) work?
- Recursive hydration is automatic—if a property is an object (e.g., `Address`), DataModel will hydrate it recursively with the same `from($data)` logic. For circular references (e.g., `User->Address->User`), you can disable recursion or use a `max_depth` parameter to avoid infinite loops.
- Can I use this with Eloquent models or Laravel’s Query Builder?
- Yes, you can extend Eloquent models to return DataModel instances (e.g., `User::query()->getDataModels()`) or add a `toDataModel()` method to convert records into typed DTOs. It’s also compatible with Query Builder results, though you’d need to manually map collections.
- What if I need to ignore a property during hydration (e.g., non-serializable closures)?
- Use the `#[Describe(['ignore' => true])]` attribute on the property to exclude it from hydration. This is useful for non-serializable data (like closures) or sensitive fields you don’t want to expose in API responses.
- How does performance compare to manual hydration or `spatie/array-to-object`?
- Reflection adds overhead, but it’s negligible for most use cases. For high-throughput APIs (10K+ requests/sec), cache attribute metadata during `composer dump-autoload` or benchmark against manual hydration. It’s generally faster than `spatie/array-to-object` for typed objects due to optimized reflection caching.
- Can I generate OpenAPI schemas or IDE autocompletion from `#[Describe]` attributes?
- While the package doesn’t include schema generation out of the box, the structured `#[Describe]` attributes make it easy to integrate with tools like `zircote/swagger-php` or custom scripts. IDEs like PHPStorm/VSCode will autocomplete properties and attributes once the package is installed.
- What happens if validation fails during hydration? Does it throw Laravel exceptions?
- By default, it throws `PropertyRequiredException` or `PropertyValidationException` for invalid data. You can extend these to Laravel’s `HttpResponseException` for API consistency or catch them globally in a `try-catch` block to return structured errors.
- How do I migrate from manual DTOs or `spatie/array-to-object` to this package?
- Start by adding the `DataModel` trait to one DTO class and replace manual hydration with `from($data)`. Use `#[Describe]` to migrate validation/casting rules incrementally. For `spatie/array-to-object`, the switch is straightforward since both use array-to-object mapping, but DataModel adds type safety and attributes.