Request Class
The Request class is the base class for all request DTOs. Extend it to define your request structures.
Usage
use Solo\RequestHandler\Attributes\Field;
use Solo\RequestHandler\Request;
final class CreateUserRequest extends Request
{
#[Field(rules: 'required|string|max:255')]
public string $name;
#[Field(rules: 'required|email')]
public string $email;
#[Field(rules: 'nullable|string')]
public ?string $bio = null;
}Methods
toArray()
Convert all initialized properties to an array. Excludes fields with exclude: true.
public function toArray(): arrayReturns: Associative array of property names to values.
Example:
$dto->name = 'John';
$dto->email = 'john@example.com';
$data = $dto->toArray();
// ['name' => 'John', 'email' => 'john@example.com']Uninitialized Properties
Properties that were not in the request (and have no default value) are not included in the result.
has()
Check if a property is initialized (was present in the request or has a default value).
public function has(string $name): boolParameters:
| Name | Type | Description |
|---|---|---|
$name | string | Property name to check |
Returns: true if property is initialized, false otherwise.
Example:
if ($dto->has('bio')) {
echo $dto->bio;
}get()
Get property value with optional default for uninitialized properties.
public function get(string $name, mixed $default = null): mixedParameters:
| Name | Type | Description |
|---|---|---|
$name | string | Property name |
$default | mixed | Default value if not initialized |
Returns: Property value or default.
Example:
$bio = $dto->get('bio', 'No bio provided');group()
Get all fields belonging to a specific group as a flat array.
public function group(string $groupName): arrayParameters:
| Name | Type | Description |
|---|---|---|
$groupName | string | Name of the group to extract |
Returns: Flat array of grouped field values.
Behavior:
- Array properties: contents are merged into result
- Scalar properties: added by property name
- Throws
LogicExceptionon duplicate keys
Example:
final class SearchRequest extends Request
{
#[Field(group: 'filters')]
public array $search = [];
#[Field(group: 'filters')]
public ?string $status = null;
#[Field(group: 'pagination')]
public int $page = 1;
}
$filters = $dto->group('filters');
// ['name' => 'test', 'status' => 'active']
$pagination = $dto->group('pagination');
// ['page' => 1]See Field Grouping for details.
getMessages()
Get custom validation error messages defined in the request class.
public function getMessages(): arrayReturns: Associative array of message overrides.
Example:
final class RegisterRequest extends Request
{
#[Field(rules: 'required|email')]
public string $email;
protected function messages(): array
{
return [
'email.required' => 'Please enter your email',
'email.email' => 'Invalid email format',
];
}
}
$dto->getMessages();
// ['email.required' => 'Please enter your email', ...]clearGroupCache()
Clear the static group cache. Useful for long-running processes.
public static function clearGroupCache(?string $className = null): voidParameters:
| Name | Type | Description |
|---|---|---|
$className | ?string | Clear specific class cache, or all if null |
Example:
// Clear all cache
Request::clearGroupCache();
// Clear specific class
Request::clearGroupCache(SearchRequest::class);Protected Methods
messages()
Override this method to provide custom validation error messages.
protected function messages(): arrayReturns: Array mapping field.rule to custom message.
Example:
protected function messages(): array
{
return [
'name.required' => 'Name cannot be empty',
'email.email' => 'Please provide a valid email address',
'age.min' => 'You must be at least 18 years old',
];
}Direct Property Access
Properties can be accessed directly when initialized:
$dto = $handler->handle(UserRequest::class, $request);
echo $dto->name; // Works if 'name' was in request
echo $dto->email; // Works if 'email' was in requestUninitialized Access
Accessing an uninitialized property throws a PHP Error:
// If 'bio' was not in request and has no default:
echo $dto->bio; // Error: must not be accessed before initialization
// Use has() or get() instead:
if ($dto->has('bio')) {
echo $dto->bio;
}
// Or:
echo $dto->get('bio', 'Default value');Best Practices
Always Use Defaults for Optional Fields
// ✅ Good: optional with default
public ?string $bio = null;
public int $page = 1;
// ❌ Bad: optional without default (requires has() check)
public ?string $bio;Use Strict Types
<?php
declare(strict_types=1);
final class MyRequest extends Request
{
// ...
}Keep DTOs Final
// ✅ Recommended
final class CreateUserRequest extends Request {}
// ❌ Avoid inheritance chains
class BaseUserRequest extends Request {}
class CreateUserRequest extends BaseUserRequest {}