Typed, validated input DTOs for PHP 8.3+. Mark a class #[Input] and declare its fields in the constructor: the factory reads them from the request, validates and casts the whole input, then calls the constructor. You get a complete, typed object, and as a readonly class it cannot change.
composer require solophp/inputRequires PHP 8.3+, a PSR-7 implementation and a validator implementing Solo\Contracts\Validator\ValidatorInterface that checks a missing or null field by presence rules only, as the interface says since solophp/contracts 1.8 — such as solophp/validator 4.2 or later.
use Solo\Input\Attributes\Input;
use Solo\Input\Attributes\Source\FromRoute;
use Solo\Input\Attributes\Validate;
use Solo\Input\InputFactory;
#[Input]
final readonly class UpdateProductInput
{
public function __construct(
#[FromRoute]
#[Validate('required|integer')]
public int $id,
#[Validate('required|string|max:255')]
public string $name,
#[Validate('required|numeric|min_value:0')]
public float $price,
#[Validate('integer|min_value:0')]
public int $stock = 0,
) {
}
}
$factory = new InputFactory($validator);
// PUT /products/{id}
$input = $factory->fromBody(UpdateProductInput::class, $request, route: ['id' => $productId]);
$input->id; // int, from the URL path
$input->name; // string, from the body
$input->stock; // int, 0 when the client left it out or sent no valueInvalid input throws one ValidationException with every error, keyed by the field the client sent.
- Installation
- Quick Start
- Configuration
- Upgrading from 1.0
- Attributes
- Type Casting
- Processing Stages
- Generators
- Nested Objects & Items
- Field Grouping
- Validation
- Schema Export
- API Reference
MIT. See LICENSE.