Casting Attributes
Reference for type casting attributes and 20+ built-in cast classes.
Understanding Type Casting in SimpleDtos
Section titled “Understanding Type Casting in SimpleDtos”Casting Priority (Highest to Lowest)
Section titled “Casting Priority (Highest to Lowest)”SimpleDtos apply casts in the following order:
- Explicit
#[Cast]attributes (highest priority) - Attribute-based casts (
#[DataCollectionOf],#[ConvertEmptyToNull]) - Nested DTOs (always auto-casted, unless
#[NoCasts]is used) #[AutoCast]for native types (lowest priority, opt-in)
What Gets Casted Automatically?
Section titled “What Gets Casted Automatically?”| Type | Without #[AutoCast] | With #[AutoCast] | With #[NoCasts] |
|---|---|---|---|
| Nested DTOs | ✅ Auto-casted | ✅ Auto-casted | ❌ Disabled |
| Native types (int, string, etc.) | ❌ TypeError | ✅ Auto-casted | ❌ TypeError |
Explicit #[Cast] | ✅ Applied | ✅ Applied | ❌ Disabled |
The AutoCast Attribute
Section titled “The AutoCast Attribute”#[AutoCast]
Section titled “#[AutoCast]”Enable automatic native PHP type casting for primitive types (opt-in).
use event4u\DataHelpers\SimpleDto\Attributes\AutoCast;
// Class-level: Enable for ALL properties#[AutoCast]class UserDto extends SimpleDto{ public readonly int $id; // "123" → 123 ✅ public readonly string $name; // 123 → "123" ✅}
// Property-level: Enable for specific propertiesclass UserDto extends SimpleDto{ #[AutoCast] public readonly int $id; // "123" → 123 ✅
public readonly string $name; // Must be string (no conversion)}Key Points:
- ✅ Automatic type casting is opt-in (not enabled by default)
- ✅ Only affects native PHP types (int, string, float, bool, array)
- ✅ Nested DTOs are always auto-casted (even without
#[AutoCast]) - ✅ Explicit casts (like
#[Cast]) ALWAYS work, regardless of#[AutoCast] - ✅ Use
#[AutoCast]for CSV/XML imports or inconsistent data sources - ✅ Skip
#[AutoCast]for better performance and strict type checking
Nested DTOs (Always Auto-Casted)
Section titled “Nested DTOs (Always Auto-Casted)”Nested DTOs are always automatically casted, even without #[AutoCast]:
class AddressDto extends SimpleDto{ public function __construct( public readonly string $street, public readonly string $city, ) {}}
class UserDto extends SimpleDto{ public function __construct( public readonly string $name, public readonly AddressDto $address, // ← Always auto-casted! ) {}}
// Array is automatically converted to AddressDto$user = UserDto::fromArray([ 'name' => 'John', 'address' => ['street' => 'Main St', 'city' => 'NYC'], // ← Array → AddressDto]);To disable nested DTO casting, use #[NoCasts]:
use event4u\DataHelpers\SimpleDto\Attributes\NoCasts;
#[NoCasts]class StrictUserDto extends SimpleDto{ public function __construct( public readonly string $name, public readonly AddressDto $address, // ← Must be AddressDto object! ) {}}
// ❌ TypeError - array is not auto-casted with #[NoCasts]$user = StrictUserDto::fromArray([ 'name' => 'John', 'address' => ['street' => 'Main St', 'city' => 'NYC'],]);
// ✅ Works - pass AddressDto object$user = StrictUserDto::fromArray([ 'name' => 'John', 'address' => AddressDto::fromArray(['street' => 'Main St', 'city' => 'NYC']),]);The Cast Attribute
Section titled “The Cast Attribute”#[Cast(string $castClass)]
Section titled “#[Cast(string $castClass)]”Cast property to a specific type (always applied, regardless of #[AutoCast]):
use event4u\DataHelpers\SimpleDto\Attributes\Cast;use event4u\DataHelpers\SimpleDto\Casts\DateTimeCast;
#[Cast(DateTimeCast::class)]public readonly Carbon $createdAt;Note: #[Cast] attributes are disabled by #[NoCasts] for maximum performance.
Built-in Cast Classes
Section titled “Built-in Cast Classes”Primitive Types
Section titled “Primitive Types”#[Cast(StringCast::class)] // Cast to string#[Cast(IntCast::class)] // Cast to integer#[Cast(FloatCast::class)] // Cast to float#[Cast(BoolCast::class)] // Cast to boolean#[Cast(ArrayCast::class)] // Cast to arrayDate & Time
Section titled “Date & Time”#[Cast(DateTimeCast::class)] // Cast to Carbon#[Cast(DateCast::class)] // Cast to Carbon (date only)#[Cast(TimestampCast::class)] // Cast from timestamp#[Cast(EnumCast::class)] // Cast to enum#[Cast(BackedEnumCast::class)] // Cast to backed enumCollections
Section titled “Collections”#[Cast(CollectionCast::class)] // Cast to Collection#[Cast(DataCollectionCast::class)] // Cast to DataCollectionObjects & JSON
Section titled “Objects & JSON”#[Cast(ObjectCast::class)] // Cast to object#[Cast(JsonCast::class)] // Cast JSON to arraySecurity
Section titled “Security”#[Cast(EncryptedCast::class)] // Encrypt/decrypt#[Cast(HashCast::class)] // One-way hash#[Cast(DecimalCast::class)] // Cast to decimal#[Cast(UuidCast::class)] // Cast to UUID#[Cast(IpAddressCast::class)] // Cast to IP address#[Cast(UrlCast::class)] // Cast to URLCast Options
Section titled “Cast Options”// Date format#[Cast(DateTimeCast::class, format: 'Y-m-d H:i:s')]public readonly Carbon $createdAt;
// Nullable cast#[Cast(IntCast::class, nullable: true)]public readonly ?int $age;
// Default value#[Cast(StringCast::class, default: 'N/A')]public readonly string $name;Custom Casts
Section titled “Custom Casts”use event4u\DataHelpers\SimpleDto\Contracts\Cast;
class UpperCaseCast implements Cast{ public function cast(mixed $value): string { return strtoupper((string) $value); }}
#[Cast(UpperCaseCast::class)]public readonly string $name;Real-World Example
Section titled “Real-World Example”class UserDto extends SimpleDto{ public function __construct( #[Cast(StringCast::class)] public readonly string $name,
#[Cast(DateTimeCast::class)] public readonly Carbon $birthDate,
#[Cast(EnumCast::class)] public readonly Status $status,
#[Cast(EncryptedCast::class)] public readonly string $ssn, ) {}}Interaction with Performance Attributes
Section titled “Interaction with Performance Attributes”Performance attributes can disable casting operations:
#[NoCasts] - Disables ALL Casts
Section titled “#[NoCasts] - Disables ALL Casts”use event4u\DataHelpers\SimpleDto\Attributes\NoCasts;
#[NoCasts]class StrictDto extends SimpleDto{ public function __construct( public readonly int $age, public readonly AddressDto $address, #[Cast(DateTimeCast::class)] public readonly Carbon $date, ) {}}
// ❌ ALL casts are disabled:// - Native types: TypeError if wrong type// - Nested DTOs: TypeError if array (must be object)// - Explicit #[Cast]: Disabled#[NoAttributes] - Disables Attribute-Based Casts
Section titled “#[NoAttributes] - Disables Attribute-Based Casts”use event4u\DataHelpers\SimpleDto\Attributes\NoAttributes;
#[NoAttributes]class SimpleDto extends SimpleDto{ public function __construct( public readonly int $age, public readonly AddressDto $address, #[Cast(DateTimeCast::class)] // ← Disabled! public readonly Carbon $date, ) {}}
// ✅ Nested DTOs still work (always auto-casted)// ❌ #[Cast] attributes are disabled// ❌ Native types: TypeError if wrong type (no AutoCast)Comparison
Section titled “Comparison”| Attribute | Nested DTOs | Native Types | Explicit #[Cast] |
|---|---|---|---|
| None | ✅ Auto | ❌ TypeError | ✅ Applied |
#[AutoCast] | ✅ Auto | ✅ Auto | ✅ Applied |
#[NoCasts] | ❌ TypeError | ❌ TypeError | ❌ Disabled |
#[NoAttributes] | ✅ Auto | ❌ TypeError | ❌ Disabled |
See Performance Attributes for more details.
See Also
Section titled “See Also”- Type Casting - Detailed guide
- Performance Attributes - Performance optimization
- Validation Attributes - Validation reference