Customizing Data Transformations with Laravel Casts
Published on by Harris Raftopoulos
Laravel's custom casts enable tailored data transformations, extending beyond built-in casting capabilities to handle complex data types and business logic.
Here is an example of using a phone number formatter using custom casts:
<?php namespace App\Casts; use Illuminate\Contracts\Database\Eloquent\CastsAttributes;use Illuminate\Database\Eloquent\Model; class PhoneNumber implements CastsAttributes{ public function get(Model $model, string $key, mixed $value, array $attributes): string { return sprintf( "+%d (%d) %d-%d", ...explode('|', $value) ); } public function set(Model $model, string $key, mixed $value, array $attributes): string { $value = preg_replace('/[^0-9]/', '', $value); return implode('|', [ substr($value, 0, 1), substr($value, 1, 3), substr($value, 4, 3), substr($value, 7) ]); }}
And another example of using an address formatter:
<?php namespace App\Casts; use Illuminate\Contracts\Database\Eloquent\CastsAttributes;use Illuminate\Database\Eloquent\Model; class Address implements CastsAttributes{ public function get(Model $model, string $key, mixed $value, array $attributes): array { $data = json_decode($value, true); return [ 'street' => $data['street'], 'city' => $data['city'], 'state' => $data['state'], 'postal_code' => $data['postal_code'], 'formatted' => sprintf( '%s, %s, %s %s', $data['street'], $data['city'], $data['state'], $data['postal_code'] ) ]; } public function set(Model $model, string $key, mixed $value, array $attributes): string { return json_encode([ 'street' => $value['street'], 'city' => $value['city'], 'state' => $value['state'], 'postal_code' => $value['postal_code'] ]); }}
Then, in your model you'll be able to use both in a situation like this:
class User extends Model{ protected $casts = [ 'address' => Address::class, 'phone' => PhoneNumber::class ];}
Custom casts provide a clean, reusable way to handle complex data transformations while keeping your models lean and maintainable.