Projectsphp-dataName Mapping

PHP Data

Package

Lightweight, framework-agnostic Data Transfer Object (DTO) library with first-class Laravel integration.

Name Mapping

Map PHP property names to different keys in input and output payloads — useful when APIs use snake_case while your Data objects stay camelCase.

Import attributes from BradieTilley\Data\Attributes.

MapName

Maps a property to a different key name during hydration and serialization.

use BradieTilley\Data\Attributes\MapName;

class UserData extends Data
{
    public function __construct(
        // A single name applies to both input and output:
        #[MapName('full_name')]
        public string $fullName,
        // Or set distinct input/output keys:
        #[MapName(output: 'email_address', input: 'email')]
        public string $emailAddress,
        // Input only — output keeps the PHP property name:
        #[MapName(input: 'phone_number')]
        public string $phone,
    ) {}
}

UserData::from([
    'full_name' => 'Ada',
    'email' => 'ada@example.com',
    'phone_number' => '555-0100',
])->toArray();
// ['full_name' => 'Ada', 'email_address' => 'ada@example.com', 'phone' => '555-0100']

Hydration reads the mapped input key first, then falls back to the real property name, then positional index. make() always uses the real (PHP) property names.

Partials (only, except, include, exclude) also use the real PHP property names — see Serialization.

SnakeCaseInput / SnakeCaseOutput

Class-level shortcuts that map every property to/from snake_case. Useful when your payloads are snake_cased while PHP properties stay camelCase.

use BradieTilley\Data\Attributes\SnakeCaseInput;
use BradieTilley\Data\Attributes\SnakeCaseOutput;

#[SnakeCaseInput]
#[SnakeCaseOutput]
class UserData extends Data
{
    public function __construct(
        public string $fullName,
        public string $emailAddress,
    ) {}
}

UserData::from(['full_name' => 'Ada', 'email_address' => 'ada@example.com'])->toArray();
// ['full_name' => 'Ada', 'email_address' => 'ada@example.com']

Apply either attribute alone when you only need one direction. Per-property #[MapName] mappings take precedence over these class-level attributes.