Type Casting

Automatic conversion between PHP types and database values.

Table of contents

Overview

Rowcast automatically casts database values to the PHP types declared on your DTO properties, and converts PHP values back to database-compatible formats on write.


Read (Database → PHP)

Database value PHP property type Result
"42" int 42
"3.14" float 3.14
"1" / "0" bool true / false
42 string "42"
"2025-06-15 10:30:00" DateTimeImmutable DateTimeImmutable object
"2025-06-15 10:30:00" DateTimeInterface DateTimeImmutable object
"2025-06-15 10:30:00" DateTime DateTime object
"active" UserStatus (BackedEnum) UserStatus::Active
NULL ?int, ?string, etc. null

Write (PHP → Database)

PHP value Database value
true / false 1 / 0
DateTimeInterface "Y-m-d H:i:s" string
BackedEnum Backing value (int/string)
null NULL
Scalars Passed through as-is

Built-in Type Casters

ScalarTypeCaster

Handles int, float, bool, and string conversions:

// Database "42" → PHP int 42
// Database "3.14" → PHP float 3.14
// Database "1" → PHP bool true
// Database 42 → PHP string "42"

DateTimeTypeCaster

Handles DateTime, DateTimeImmutable, and DateTimeInterface:

class Post
{
    public int $id;
    public string $title;
    public DateTimeImmutable $createdAt;
    public DateTime $updatedAt;
}

// Read: "2025-06-15 10:30:00" → DateTimeImmutable object
// Write: DateTimeImmutable → "2025-06-15 10:30:00"

When the property type is DateTimeInterface, the value is always resolved to DateTimeImmutable.

EnumTypeCaster

Handles any BackedEnum:

enum Status: string
{
    case Active = 'active';
    case Inactive = 'inactive';
    case Banned = 'banned';
}

class UserDto
{
    public int $id;
    public Status $status;
    public ?Status $previousStatus;  // nullable enums supported
}

// Read: "active" → Status::Active
// Write: Status::Active → "active"

Custom Type Caster

Implement TypeCasterInterface to support additional types:

use AsceticSoft\Rowcast\TypeCaster\TypeCasterInterface;

class UuidTypeCaster implements TypeCasterInterface
{
    public function supports(string $type): bool
    {
        return $type === Uuid::class;
    }

    public function cast(mixed $value, string $type): Uuid
    {
        return new Uuid((string) $value);
    }
}

Registering a custom caster

use AsceticSoft\Rowcast\TypeCaster\TypeCasterRegistry;

$registry = TypeCasterRegistry::createDefault();
$registry->addCaster(new UuidTypeCaster());

Using the custom registry

Pass a custom hydrator with the registry to DataMapper:

use AsceticSoft\Rowcast\Hydration\ReflectionHydrator;
use AsceticSoft\Rowcast\DataMapper;

$hydrator = new ReflectionHydrator(typeCaster: $registry);
$mapper = new DataMapper($connection, hydrator: $hydrator);

The TypeCasterRegistry::createDefault() method returns a registry with all built-in casters pre-registered. Use addCaster() to extend it with your own.