zero-to-prod/data-model
Reflection-based PHP data models that hydrate from arrays/objects via a single from() call. Use attributes to centralize casting, validation, defaults, required/nullable rules, and assignment behavior—ideal for external data like APIs, DB rows, and user input.
new User($data)) with type-safe, declarative alternatives. This directly addresses Laravel’s common pain points in API responses, form requests, and database hydration.#[Describe] rules), Eloquent models (recursive hydration), and API contracts (e.g., #[Describe('required')] for FormRequest validation).isset(), array_get(), and constructor logic, aligning with Laravel’s philosophy of "convention over configuration" while adding explicit control.use DataModel; and #[Describe] attributes—no base classes, interfaces, or complex setup. Laravel’s attribute support (PHP 8+) ensures zero compatibility issues.Laravel Validation example in the README demonstrates how #[Describe] rules can directly map to Laravel’s validation rules (e.g., required, nullable), reducing duplication between DTOs and FormRequest classes.User with Address), which is critical for Laravel’s Eloquent relationships and API payloads.#[Describe] is powerful, overuse could clutter classes. Mitigation: Use sparingly for complex transformations; default to type hints for simple cases.fillable/guarded. Solution: Use via to delegate to Eloquent’s fill() or create().assign or via with container-bound classes, ensure dependencies are resolvable. Test with Laravel’s bind() or make().FormRequest validation logic? (Potential: Merge #[Describe] rules into rules() array.)#[Describe] configurations? (Suggestion: Static analysis tools like PHPStan or custom tests for attribute validation.)ReflectionProperty instances.#[Describe] for new DTOs, or will it remain optional? (Suggestion: Enforce via a custom PHPCS rule or Laravel policy.)LaravelDataModel trait to integrate with Eloquent, validation, or API resources? (Example: Auto-register #[Describe] rules in FormRequest::rules().)Resource::toArray() with DataModel::from($data) for type-safe responses.#[Describe] to define validation rules, eliminating duplicate rules() arrays.fill() calls.DataModel::from($request->all()) for cleaner service boundaries.CreateUserRequest with #[Describe] attributes for validation.DataModel for simple hydration (e.g., User::from($request->all())).#[Describe] for validation/casting (e.g., #[Describe(['required', 'cast' => 'strtoupper'])]).fill() calls with recursive hydration for nested objects.FormRequest::rules() from #[Describe] attributes.// In a FormRequest:
#[Describe(['required', 'min' => 18])]
public int $age;
→ Automatically maps to rules(['age' => 'required|min:18']).DataModel::from().DataModel::from() won’t break existing constructors (though constructors may become redundant).#[Describe] → rules()) or third-party libraries like Respect/Validation.via to delegate to Model::fill() or Model::create() for database hydration.Collection::map(fn($item) => User::from($item)).DataModel.UserResource → UserDataModel with #[Describe] for serialization.FormRequest classes to use #[Describe] for validation.DataModel::from().Model::fill() with DataModel::from() for API-driven model creation.#[Describe] attributes, reducing scattered validation/transformation code.#[Describe(['cast' => 'strtoupper'])] clarifies intent).#[Describe] could make classes harder to read. Mitigation: Use for complex logic only; default to type hints.pre/post hooks or custom via methods may require deeper debugging. Solution: Add logging or use Xdebug for complex flows.#[Describe] configurations at development time.#[Describe] keys and their Laravel equivalents (e.g., required → required|sometimes).required vs. nullable vs. default.User ↔ Order).PropertyRequiredException messages for user-friendly API errors.try {
$user = User::from($request->all());
} catch (PropertyRequired
How can I help you explore Laravel packages today?