Back to all funny docs

Eloquent: The Magic of Mutators & Casting! ๐ŸŽฉโœจ

Warning: May cause actual learning AND laughter!

Eloquent: The Magic of Mutators & Casting! ๐ŸŽฉโœจ

Introduction ๐ŸŽ‰๐ŸŽˆ

Welcome, brave coders! Today weโ€™re diving into the mystical world of Eloquent Model mutators and casting - a magical journey where data transforms with ease and elegance. Grab your wands (keyboards) and letโ€™s get started! โœจ๐Ÿง™โ€โ™‚๏ธ

Accessors & Mutators: The Sorcererโ€™s Apprentices ๐Ÿงโ€โ™‚๏ธ๐Ÿงโ€โ™€๏ธ

Defining an Accessor ๐Ÿ”

Transform data like a master alchemist! With accessors, you can return transformed data without changing the original value. Itโ€™s like reading a spellbook but in PHP! ๐Ÿ“–

public function getNameAttribute($value) {
    return ucfirst($value);
}

Defining a Mutator ๐Ÿ”จ

Mutate data as if by magic! With mutators, you can change the original value before itโ€™s saved. Itโ€™s like enchanting an item in your favorite RPG game! ๐Ÿ›ก๏ธ๐Ÿงช

public function setNameAttribute($value) {
    $this->attributes['name'] = strtolower($value);
}

Attribute Casting: Turning Cinders into Pumpkins ๐ŸŽƒ๐ŸŒˆ

Array and JSON Casting ๐Ÿ“œ

Transform data into arrays or JSON for easy manipulation. Itโ€™s like learning the spell of โ€œExpelliarmusโ€ on your data! ๐Ÿค“

protected $casts = [
    'options' => 'array',
];

Binary Casting ๐Ÿ’พ

Store binary data as base64 strings. Itโ€™s like casting a spell to turn data into invisible ink! ๐Ÿ•ต๏ธโ€โ™‚๏ธ

protected $casts = [
    'logo' => 'binary',
];

Date Casting ๐Ÿ“…

Transform dates into a human-readable format. Itโ€™s like casting a spell to make time stand still for a moment! โฐ

protected $dates = ['created_at', 'updated_at'];

Enum Casting ๐ŸŒˆ

Restrict values to a predefined set. Itโ€™s like casting a spell that limits the elements of your spells! ๐Ÿง™โ€โ™€๏ธ๐Ÿช„

protected $enum = [
    'status' => Status::class,
];

Encrypted Casting ๐Ÿ”

Encrypt sensitive data for security. Itโ€™s like casting a spell to protect your secrets! ๐Ÿฐ

protected $encryption = 'AES-256-CBC';
protected $key = env('ENCRYPTION_KEY');

Query Time Casting ๐Ÿ•’

Cast data as you query it. Itโ€™s like casting a spell that filters your data on the fly! ๐Ÿš€

public function scopeActive($query) {
    return $query->where('status', Status::ACTIVE);
}

Custom Casts: Crafting Your Own Spells ๐Ÿง™โ€โ™‚๏ธ๐Ÿ”ฎ

Value Object Casting ๐Ÿ“ฆ

Create custom casts for value objects. Itโ€™s like crafting your own magic spells! ๐Ÿž๏ธ๐Ÿ’ซ

class MoneyCast implements ShouldCastAsInterface {
    // ...
}

Array / JSON Serialization ๐Ÿ“œ๐Ÿ”„

Serialize data into arrays or JSON. Itโ€™s like casting a spell to make your data more magical! โœจ๐ŸŒˆ

public function serialize($attribute, $value) {
    // ...
}

public function deserialize($attribute, $value) {
    // ...
}

Inbound Casting ๐Ÿ›ก๏ธ๐Ÿ”„

Transform data before itโ€™s saved. Itโ€™s like casting a spell to protect your data from harm! ๐Ÿ›ก๏ธ

public function setAttribute($attribute, $value) {
    // ...
}

Cast Parameters ๐Ÿ”„๐Ÿ“

Pass additional parameters to your custom casts. Itโ€™s like adding extra ingredients to your magic potion! ๐Ÿงช๐Ÿฅค

public function getAttribute($attribute, $value) {
    // ...
}

public function setAttribute($attribute, $value) {
    // ...
}

Comparing Cast Values ๐Ÿ”๐Ÿ’ฌ

Compare cast values as if they were already transformed. Itโ€™s like comparing two spells without actually casting them! ๐Ÿง™โ€โ™‚๏ธ๐Ÿง™โ€โ™€๏ธ

public function asArray() {
    // ...
}

Castables ๐Ÿ“œ๐Ÿ“

Specify what data types your custom cast can handle. Itโ€™s like setting the limitations of your magic spells! ๐Ÿง™โ€โ™€๏ธ๐Ÿ•ฏ๏ธ

Hey There, Coders! ๐Ÿค–๐Ÿš€

Ever felt like your data needs a little makeover? Well, buckle up, because weโ€™re diving into the world of Eloquent Attribute Transformations! These bad boys - Accessors, Mutators, and Attribute Casting - are your new BFFs when it comes to sprucing up model instances.

Think of them as your dataโ€™s personal stylists who work behind the scenes, making sure everything looks fabulous before they hit the runway (aka, when you access or set values on those models).

Letโ€™s say you want to encrypt sensitive info like your grandmaโ€™s secret chocolate chip cookie recipe while itโ€™s safe-kept in the database. With Laravel Encrypter (check out our Encryption docs), you can! Then, voilร , it gets automatically decrypted for you when you access that Eloquent model like a VIP backstage pass.

Or maybe youโ€™ve got a JSON string stored in your database thatโ€™s just begging to be turned into an array. Well, who are we to deny them their dreams? Accessor and Mutator magic transforms that string into an array as soon as itโ€™s accessed via your Eloquent model! ๐Ÿค–๐Ÿ’ฅ๐Ÿค–

Now, arenโ€™t data transformations more fun with a side of sass? ๐Ÿ˜Ž๐ŸŽ‰ Letโ€™s get started on making your modelsโ€™ lives (and yours!) more fabulous than ever! ๐Ÿš€๐Ÿ’–

Unveiling the Magic Mirror: Accessors and Mutators! โœจ๐Ÿช„

In the mystical kingdom of Laravel, data is no longer a simple reflection in a pool. Instead, itโ€™s a glamorous queen (or king) who may need some help to look her best before being presented to the world. Thatโ€™s where Accessors and Mutators come into play! They are your trusted magicians, transforming data like Cinderellaโ€™s fairy godmother ๐Ÿ‘ฝโœจ

Defining an Accessor ๐Ÿ”ฎ

An Accessor is a spell that lets you see a more beautiful version of your data. Itโ€™s like those magical mirrors in fairy tales that make the ugly duckling look swan-tastic! To cast this spell, just add get before your attribute name in the getters section of your Model.

class User extends Authenticatable {
    //...

    public function getFullNameAttribute() {
        return $this->first_name . ' ' . $this->last_name;
    }
}

Now, whenever you call $user->full_name, it will return the userโ€™s full name like a charm! ๐ŸŽฉ๐Ÿ‘‘

Defining a Mutator ๐Ÿงžโ€โ™‚๏ธ

A Mutator is a powerful potion that gives your data a new lease of life. Imagine if the pumpkin could become a carriage just by sprinkling fairy dust! In Laravel, Mutators do exactly that. They help you change, translate, or manipulate data before itโ€™s saved into the database.

To brew this potion, add set before your attribute name in the setters section of your Model, then cast the data as desired.

class User extends Authenticatable {
    //...

    public function setFirstNameAttribute($value) {
        $this->attributes['first_name'] = ucfirst($value);
    }
}

Now, if you try to update a userโ€™s first name like this: $user->first_name = 'tom';, the first letter will magically transform into an uppercase T! ๐Ÿคฏ๐ŸŽ‰

So there you have it โ€“ Accessors and Mutators are your secret weapons in making data beautiful, elegant, and perfectly suited for presentation in Laravelโ€™s wonderful world! ๐ŸŒน๐Ÿ’Žโœจ

Transforming Attributes with Style!

Ahoy there, coders! Letโ€™s talk about accessors, the superheroes of your Laravel models that step in when you need to spruce up an attribute value. To create one, just whip up a protected method on your model, naming it after the camel-cased version of your modelโ€™s true underlying attribute or database column (if applicable).

Take our example first_name attribute, which weโ€™re about to transform into something that would make Mr. Darcy proud! Our accessor will be called automatically by Eloquent when someone tries to grab the first_name value. But remember, all accessor and mutator methods should hint at returning the noble Illuminate\Database\Eloquent\Casts\Attribute.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Get the user's first name, fit for a Jane Austen novel.
     */
    protected function properFirstName(): Attribute
    {
        return Attribute::make(
            get: fn (string $value) => ucfirst($value),
        );
    }
}

See that? Weโ€™ve just made every userโ€™s first name a perfect opener for a conversation. But remember, our accessor doesnโ€™t end there! We can still manipulate the original value and return it as we please. To get your hands on this freshly-pressed first name, simply ask for it using your model instance:

use App\Models\User;

$user = User::find(1);

$firstName = $user->properFirstName; // Now, isn't that a civilized way to start a conversation?

โš ๏ธ TIP: To get these refined values sprinkled into the array or JSON versions of your glamorous model, youโ€™d better append them! Hereโ€™s a fancy tutorial on how to do just that.

In the grand world of Laravel, where models strut their stuff like peacocks with too much time on their hands (but who can blame them?), there comes a moment when your accessor decides itโ€™s time to don a tuxedo and transform multiple model attributes into one dashing โ€˜Value Objectโ€™. Fret not, for this is as easy as teaching a newborn to pirouette!

Your get closure, ever the charming host at a fancy ball, may find itself welcoming an extra guest named $attributes. This suave gentleman will waltz into the scene automatically and gracefully present an array of all your modelโ€™s current attributes.

Use the Address from our very own App as a date for the evening,
and Illuminate\Database\Eloquent\Casts\Attribute as the matchmaker.

/**
 * Dance with the user's address.
 */
protected function address(): Attribute
{
    return Attribute::make(
        get: fn (mixed $value, array $attributes) => new App\Support\Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
    );
}

Now, isnโ€™t that a swell little dance routine? Your model can now tango with multiple attributes and transform them into one glamorous value object. And who knows, maybe this newfound charm will even help them snag the โ€œModel of the Yearโ€ award at the Laravel Ball! ๐Ÿคฉโœจ๐Ÿ’ƒ๐Ÿป๐Ÿ•บ๐Ÿป

Alright, letโ€™s dive into the whimsical world of Laravel accessor caching!

Accessor Caching: The Time-Traveling Value Buffet ๐Ÿฒ

Ever cooked a dish only to have it change right after you served it? Not cool, right? Well, Eloquent feels your pain and has come up with a solution: time travel for values! When you return a value object from an accessor, any changes made to the time-traveling dish will automatically be synced back before the model is saved. Talk about a magical kitchen! ๐Ÿ”œ

use App\Models\User;

$user = User::find(1); // Go ahead and get that user, Captain!

// Now let's update our time-traveling dish (address)
$user->address->lineOne = 'Updated Address Line 1 Value';
$user->address->lineTwo = 'Updated Address Line 2 Value';

$user->save(); // And voila! The changes are saved in no time.

But sometimes, you may want to add a little caching for light-speed computations like strings and booleans (weโ€™re talking about primitive values here, folks). To make that happen, you can invoke the shouldCache method when defining your accessor:

protected function hash(): Attribute
{
    return Attribute::make(
        get: fn (string $value) => bcrypt(gzuncompress($value)), // A complex dish recipe, I see! ๐Ÿด
    )->shouldCache(); // Add a little caching to save on those precious computing calories. ๐Ÿฅ•
}

And if youโ€™d like to opt out of the time-traveling behavior for attributes (because letโ€™s face it, some dishes need to be freshly cooked), you can invoke the withoutObjectCaching method when defining the attribute:

/**
 * Interact with the user's address.
 */
protected function address(): Attribute
{
    return Attribute::make(
        get: fn (mixed $value, array $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ), // A freshly baked address, just the way we like it! ๐Ÿ 
    )->withoutObjectCaching(); // No time travel for this dish, please. โณ
}

Now that youโ€™ve mastered the art of accessor caching, itโ€™s time to move on to mutators! Stay tuned for more fun and games in our Laravel kitchen. ๐Ÿ˜‰

Unleashing Attribute Sorcerers: Mutators, Your Magic Cloak for Eloquent Models! ror

In a fantasy realm where your models are the knights and attributes are the glorious steeds they ride into battle, mutators are the magical cloaks that transform those horses (or whatever medieval transportation you prefer) as they charge into combat! ๐Ÿฅฝ๐Ÿงโ€โ™‚๏ธ

To bestow this enchanting cloak upon one of your Eloquent attributes, simply cast a spell (write some code) by providing the set incantation when defining your attribute. For instance, letโ€™s conjure up a mutator for our humble first_name attribute:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Alchemize the user's first name.
     */
    protected function firstNameAlchemy(): Attribute
    {
        return Attribute::make(
            get: fn (string $value) => ucfirst($value), // Transform the value to uppercase first letter
            set: fn (string $value) => strtolower($value), // Lowercase the value as it passes through the cloak
        );
    }
}

Once your mutator is born, it will be automatically summoned when you attempt to bestow a new value upon the first_name attribute on the model.

use App\Models\User;

$user = User::find(1); // Find our noble knight

$user->first_name = 'SALLY'; // Attempt to set a new name, triggering the mutator's set callback

In this scenario, our set spell will be invoked with the value SALLY. The mutator will then apply its lowercase charm (the strtolower function) and return the transformed name, which will then become the knightโ€™s new steed in the modelโ€™s internal $attributes array.

Double, Double Toil and Trouble: Mutate Multiple Attributes ๐Ÿง™โ€โ™‚๏ธ๐Ÿ”ฎ

Should you find yourself in need of enchanting multiple attributes at once, fear not! With a wave of your wand (or some fancy code), you can cast spells upon all the horses in your knightโ€™s stable. Just follow these simple steps:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Combine alchemy and styling for the user.
     */
    protected function userTransformations(): void
    {
        $this->firstNameAlchemy(); // Cast the first name spell
        $this->lastNameCapitalize(); // Cast the last name capitalization spell
        $this->emailCamelCase(); // Cast the email camel casing spell
    }

    /**
     * Alchemize the user's first name.
     */
    protected function firstNameAlchemy(): Attribute
    {
        return Attribute::make(
            get: fn (string $value) => ucfirst($value), // Transform the value to uppercase first letter
            set: fn (string $value) => strtolower($value), // Lowercase the value as it passes through the cloak
        );
    }

    /**
     * Capitalize the user's last name.
     */
    protected function lastNameCapitalize(): Attribute
    {
        return Attribute::make(
            get: fn (string $value) => ucfirst($value), // Transform the value to uppercase first letter
            set: 'set', // This mutator does not need to manipulate the value, so we just use the default set callback
        );
    }

    /**
     * Convert the user's email address to camelCase.
     */
    protected function emailCamelCase(): Attribute
    {
        return Attribute::make(
            get: fn (string $value) => str_replace('.', '', ucwords(strtolower($value))), // Replace dots and convert to camel case
            set: 'set', // This mutator does not need to manipulate the value, so we just use the default set callback
        );
    }
}

In this example, our User model now combines three distinct spells (mutators) to transform the first_name, last_name, and email attributes all at once. When you cast these spells upon a user instance and set new values for these attributes, the respective mutators will be automatically summoned! ๐Ÿง™โ€โ™‚๏ธ๐Ÿ”ฅ

Alrighty, buckle up, because weโ€™re about to dive into the world of Laravel attribute mutation! ๐Ÿš€๐ŸŒˆ

Multiple Attribute Makeover

In some cases, your swanky attribute mutator might fancy setting more than one model attribute. No problemo! Just return an array from the set closure and assign each key to a model attribute or database column itโ€™s associated with:

use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;

/**
 * Hang out at the user's address.
 */
protected function addressParty(): Attribute
{
    return Attribute::make(
        get: fn (mixed $value, array $attributes) => new Address(
            $attributes['street'], // Because one line just isn't enough for my house number!
            $attributes['city'],   // And we certainly need a city to host this shindig!
        ),
        set: fn (Address $value) => [
            'street' => $value->getStreet(), // Alrighty, let's get this party started on the right street!
            'city'   => $value->getCity(),   // Time to invite the neighbors and spread the word about our soiree!
        ],
    );
}

Now that weโ€™ve got the fun out of our system, letโ€™s get back to business. With this setup, your models can maintain a consistent state while handling complex data transformations. ๐ŸŽ‰๐Ÿฅณ And remember, laughter is the best medicineโ€ฆ unless you have a headache from typing too much PHP code! ๐Ÿ’Š๐Ÿค•

Super Power Casting for Your Models! ๐Ÿฆธโ€โ™‚๏ธ๐Ÿฆธโ€โ™€๏ธ

Attribute casting is like giving your models superpowers, turning them into shapeshifters without even breaking a sweat! No need to create additional methods; just use the casts method on your model to convert attributes into common data types like a boss! ๐Ÿ˜Ž

Hereโ€™s the lowdown on the cast types we support:

  • array ๐Ÿ“ฆ
  • AsFluent::class ๐ŸŽฉ (not sure who AsFluent is, but they sound fancy)
  • AsStringable::class ๐Ÿคณ (if youโ€™re in need of a talking model)
  • AsUri::class ๐ŸŒ (because who doesnโ€™t want their models to navigate the web?)
  • boolean ๐Ÿ”บ๐Ÿ”ป (good olโ€™ True or False)
  • collection ๐Ÿ“ฆ๐Ÿ“ฆ (for when your model needs a bag of tricks)
  • date ๐Ÿ—“๏ธ (because even models have birthday parties)
  • datetime ๐Ÿ•’๐Ÿ• (when you want your model to tell time like a pro)
  • immutable_date ๐Ÿ”’๐Ÿ—“๏ธ (a date thatโ€™s not allowed to change its clothes)
  • immutable_datetime ๐Ÿ”’๐Ÿ•’๐Ÿ• (the same, but with time too)
  • decimal:<precision> ๐Ÿ“Š (for models that like precision in their numbers)
  • double ๐Ÿ”ข (for those models that just canโ€™t keep it simple)
  • encrypted ๐Ÿ”’๐Ÿ—๏ธ (when your model has secrets to protect)
  • encrypted:array ๐Ÿ“ฆ๐Ÿ”’๐Ÿ—๏ธ (a bag full of secrets, no less!)
  • encrypted:collection ๐Ÿ“ฆ๐Ÿ”’๐Ÿ—๏ธ (for models that love to keep their collections under wraps)
  • encrypted:object ๐Ÿงช๐Ÿ”’๐Ÿ—๏ธ (when your model has a complex, encrypted identity)
  • float ๐Ÿ”ข (because even models like to play with numbers sometimes)
  • hashed ๐Ÿ”’๐Ÿ”จ (for models that enjoy a good password scramble)
  • integer โŒ›๏ธ (for those models who keep count of everything)
  • object ๐Ÿงช (when your model needs to be more than just data)
  • real ๐Ÿ”ข (a fancy way of saying โ€œfloatโ€)
  • string ๐Ÿ“ (because even models have things to write)
  • timestamp โฐ๐Ÿ—“๏ธ (for models that need to remember everything, always)

So, letโ€™s cast some magic on the is_admin attribute, which is stored in our database as an integer (0 or 1). Weโ€™ll turn it into a boolean value:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'is_admin' => 'boolean',
        ];
    }
}

Now, when you access the is_admin attribute, it will magically transform into a boolean, even if it was an integer in the database:

$user = App\Models\User::find(1);

if ($user->is_admin) {
    // ...
}

Need to add a temporary cast at runtime? Just use the mergeCasts method! These new cast definitions will join forces with any already defined on the model:

$user->mergeCasts([
    'is_admin' => 'integer',
    'options' => 'object',
]);

[!WARNING] Be careful, attributes that are null will not be cast. Also, donโ€™t define a cast (or an attribute) with the same name as a relationship or assign a cast to the modelโ€™s primary key. That would just be weird and confusing. ๐Ÿคฏ๐Ÿคจ

๐Ÿ”™Back to Stringable Casting

Strings-a-palooza! (A.K.A Stringable Casting)

Looking to turn your model attributes into sassy, fluent Stringable objects? Well, buddy, youโ€™ve come to the right place! The Illuminate\Database\Eloquent\Casts\AsStringable cast class is just the ticket for a jamboree of stringy goodness.

<?php

namespace App\Models;

// Import all the cool kids (Cast, AsStringable)
use Illuminate\Database\Eloquent\Casts\AsStringable;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * If you're casting a spell, you should know which attributes.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        // Here's our secret sauce: AsStringable for the directory attribute
        return [
            'directory' => AsStringable::class,
        ];
    }
}

And because we here at Laravel love a good party, letโ€™s not forget about those array and JSON castings! You can find all the deets right here. But remember, with great power comes great responsibility - use it wisely, my friend! ๐Ÿค˜

The Magic of JSON Transformation Crew (JTC)

Brace yourselves, data wranglers! Meet JTC - the extraordinary team that turns JSON into PHP arrays, and vice versa, with supernatural ease!

Hereโ€™s a classic tale about our heroic cast, the array. This guy is particularly handy when dealing with database columns that are packed like sardines in serialized JSON. Imagine your database stores a JSON or TEXT field type, filled to the brim with serialized JSON goodness - adding this magical cast to that attribute will turn it into a phwoar-worthy PHP array as soon as you summon it on your Eloquent model!

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * This is the secret incantation that calls upon our cast, the array.
     */
    protected function casts(): array
    {
        return [
            'options' => 'array', // Yes, just like a magic wand!
        ];
    }
}

Once youโ€™ve performed this mystical ritual, you can now summon the options attribute, and it will transform into a PHP array right before your eyes! But remember, with great power comes great responsibility: whenever you assign a new value to the options attribute, it gets wrapped back up in its JSON disguise for safekeeping in the database.

use App\Models\User;

$user = User::find(1);

// Gaze upon the deserialized array!
$options = $user->options;

// Add some new secrets to the mix
$options['key'] = 'value';

// Summon the transformation crew again to put the updated array back into its JSON disguise
$user->options = $options;

// Save it for posterity
$user->save();

Want a quicker way to update a single field of your JSON attribute? Give it the mass-assignment treatment and use the -> operator when invoking the update method:

$user = User::find(1);

// With a wave of your hand, make the 'options' field key take on a new value!
$user->update(['options->key' => 'value']);

Now youโ€™re well-versed in JTCโ€™s art of JSON transformation. Youโ€™re officially one step closer to mastering data manipulation! ๐Ÿคฉ๐Ÿ”ฅ๐Ÿ“š

Alright, folks! Letโ€™s dive into the whimsical world of Laravel data casting, where even Emojis and Unicode characters get their time to shine! ๐ŸŽ‰๐ŸŽค

If you find yourself yearning for a smoother way to store an array attribute thatโ€™s bursting with unescaped Unicode characters, fear not! Introducing the json:unicode cast, your new bestie in Laravel data land.

Hereโ€™s how you can get it all set up:

/**
 * Grab the attributes that deserve a fancy casting party.
 *
 * @return array<string, string>
 */
protected function casts()
{
    return [
        'options' => 'json:unicode', // It's like a magic spell for your JSON data! ๐Ÿ’ซ๐Ÿ”ฎ
    ];
}

Now, your Emojis and Unicode characters can join the party without having to worry about getting all tangled up in those pesky escape sequences. Happy casting! ๐Ÿค—๐Ÿš€

Alright, buckle up, because weโ€™re about to dive into the magical world of Laravelโ€™s Array Object and Collection Casting!

First off, letโ€™s talk about the standard array cast. Itโ€™s a swell pal for many applications, but itโ€™s got some quirks. You see, since it returns a primitive type, direct mutation of an offset array can lead to a PHP error, much like inviting a party pooper to your shindig!

$user = User::find(1);

$user->options['key'] = $value; // ๐Ÿšจ PHP Error: Call to undefined method App\Models\User::options()!

But fear not, Laravelโ€™s got your back with the AsArrayObject cast! This bad boy transforms your JSON attribute into an ArrayObject class, allowing you to modify individual offsets without triggering a PHP errorโ€”itโ€™s like having a bouncer at the door of your array, only friendlier and less prone to violence.

use Illuminate\Database\Eloquent\Casts\AsArrayObject;

/**
 * Get the attributes that should be cast.
 *
 * @return array<string, string>
 */
protected function casts(): array
{
    return [
        'options' => AsArrayObject::class,
    ];
}

Next up, we have the AsCollection cast. This one turns your JSON attribute into a Laravel Collection instance. Itโ€™s like inviting your array to a dance partyโ€”it gets spruced up and ready to boogie!

use Illuminate\Database\Eloquent\Casts\AsCollection;

/**
 * Get the attributes that should be cast.
 *
 * @return array<string, string>
 */
protected function casts(): array
{
    return [
        'options' => AsCollection::class,
    ];
}

Now, if youโ€™d like the AsCollection cast to instantiate a custom collection class instead of Laravelโ€™s base collection class, you can pass the collection class name as an argument:

use App\Collections\OptionCollection;
use Illuminate\Database\Eloquent\Casts\AsCollection;

/**
 * Get the attributes that should be cast.
 *
 * @return array<string, string>
 */
protected function casts(): array
{
    return [
        'options' => AsCollection::using(OptionCollection::class),
    ];
}

If you want to map collection items into a given class, you can use the of method and the collectionโ€™s mapInto method:

use App\ValueObjects\Option;
use Illuminate\Database\Eloquent\Casts\AsCollection;

/**
 * Get the attributes that should be cast.
 *
 * @return array<string, string>
 */
protected function casts(): array
{
    return [
        'options' => AsCollection::of(Option::class)
    ];
}

Now, when mapping collections to objects, remember these objects should implement the Illuminate\Contracts\Support\Arrayable and JsonSerializable interfaces. This helps define how their instances should be serialized into the database as JSON:

<?php

namespace App\ValueObjects;

use Illuminate\Contracts\Support\Arrayable;
use JsonSerializable;

class Option implements Arrayable, JsonSerializable
{
    public string $name;
    public mixed $value;
    public bool $isLocked;

    /**
     * Create a new Option instance.
     */
    public function __construct(array $data)
    {
        $this->name = $data['name'];
        $this->value = $data['value'];
        $this->isLocked = $data['is_locked'];
    }

    /**
     * Get the instance as an array.
     *
     * @return array{name: string, data: string, is_locked: bool}
     */
    public function toArray(): array
    {
        return [
            'name' => $this->name,
            'value' => $this->value,
            'is_locked' => $this->isLocked,
        ];
    }

    /**
     * Specify the data which should be serialized to JSON.
     *
     * @return array{name: string, data: string, is_locked: bool}
     */
    public function jsonSerialize(): array
    {
        return $this->toArray();
    }
}

And voila! Youโ€™ve just learned the art of Laravelโ€™s Array Object and Collection Casting. Now you can party with your arrays like never before! ๐Ÿ’ƒ๐Ÿผ๐Ÿ•บ๐Ÿผ

Binary Buddy System

If your Eloquent model has a posh party where the guest list includes a binary type uuid or ulid column, plus the usual auto-incrementing ID column, you can call upon the AsBinaryCast bouncer to ensure seamless transformation between the value and its binary disguise:

use Illuminate\Database\Eloquent\Casts\AsBinary;

/**
 * Decide who gets in through the gate.
 *
 * @return array<string, string>
 */
protected function getAllowedIn(): array
{
    return [
        'uuid' => AsBinary::uuid(),
        'ulid' => AsBinary::ulid(),
    ];
}

With the bouncer in place, you can invite UUID or ULID guests by setting their attribute values to an object instance or a string. Our Eloquent doorman will work his magic and convert the value into its binary representation:

use Illuminate\Support\Str;

$guest->uuid = Str::uuid();

return $guest->uuid;

// "6e8cdeed-2f32-40bd-b109-1e4405be2140" - the glamorous disguise for their binary identity

Hope youโ€™re having a swell time casting! ๐Ÿค˜๐ŸŽ‰

Alright, letโ€™s dive into the ticklish topic of Date Casting! ๐ŸŽ‰

By the way, side note: Eloquent is like that friend who always knows the right time (pun intended) and never misses a beat. It comes pre-equipped with Carbon - think of it as a swanky tuxedo over the PHP DateTime class, complete with a pocket full of useful tricks! ๐Ÿคต๏ธ

Now, if you fancy casting additional date attributes beyond the default created_at and updated_at, you can define your very own date casts within your modelโ€™s โ€˜castsโ€™ method. Itโ€™s like inviting that friend to your party โ€“ theyโ€™ll blend right in! ๐Ÿฅณ

Typically, dates should be cast using the โ€˜datetimeโ€™ or โ€˜immutable_datetimeโ€™ cast types. Think of it as wearing a formal suit for high-stakes events and an elegant cocktail dress for more casual gatherings (metaphorically speaking). ๐Ÿ˜‰

When defining a date or datetime cast, you may also specify the dateโ€™s format. This is useful when your model needs to look good on the dance floor โ€“ aka serialize to an array or JSON. Hereโ€™s the recipe for that:

/**
 * Serve up the attributes that should be cast as a delectable dish.
 *
 * @return array<string, string>
 */
protected function casts(): array
{
    return [
        'created_at' => 'datetime:Y-m-d', // The secret ingredient for a mouthwatering model!
    ];
}

When a column is cast as a date, you may set the corresponding model attribute value to various forms of time travel-worthy data. UNIX timestamp? Check. Date string (Y-m-d)? You got it. Date-time string? On it! DateTime / Carbon instance? Bring it on! The dateโ€™s value will be correctly converted and stored in your database without a hiccup. ๐Ÿš€

Fancy customizing the default serialization format for all of your modelโ€™s dates? Simply define a โ€˜serializeDateโ€™ method on your model:

/**
 * Prepare a date for a swanky dinner party (array/JSON serialization).
 */
protected function serializeDate(DateTimeInterface $date): string
{
    return $date->format('Y-m-d'); // The ultimate cocktail hour format!
}

To specify the format that should be used when actually storing a modelโ€™s dates within your database, you should use the dateFormat argument on your modelโ€™s โ€˜Tableโ€™ attribute. Itโ€™s like setting the dress code for your database โ€“ keep it classy! ๐Ÿคณ๐Ÿฝ

use Illuminate\Database\Eloquent\Attributes\Table;

#[Table(dateFormat: 'U')] // Using 'U' format โ€“ a perfect fit for timestamps!
class Flight extends Model
{
    // ...
}

Now that youโ€™ve got the hang of it, go forth and cast dates with confidence! ๐ŸŽ‰

Alrighty, buckle up, because weโ€™re about to take a wild ride through the world of Laravel date casting, serialization, and timezones! ๐Ÿš€๐Ÿ•ฐ๏ธ

By default, our date and datetime casts are like those posh British butlers who always show up in a crisp tuxedo โ€“ they convert dates into a sleek UTC ISO-8601 date string (YYYY-MM-DDTHH:MM:SS.uuuuuuZ), no matter what timezone your application thinks itโ€™s in (thanks to the timezone configuration option). Itโ€™s like theyโ€™ve all been to the same etiquette school! ๐Ÿ•บ๏ธ

Now, you might be tempted to spice things up with a custom format for your dates, like datetime:Y-m-d H:i:s. But hold your horses, partner! When this happens, the Carbon instanceโ€™s inner timezone (usually defined by that same timezone option) will take center stage during serialization. Just remember that columns like created_at and updated_at, being the timeless celebrities they are, always stick to UTC, no matter what your applicationโ€™s timezone setting might be.

Now, letโ€™s not forget about Enum casting โ€“ itโ€™s like having a personal stylist for your database columns! ๐Ÿคต๏ธ๐Ÿ‘— But thatโ€™s a whole different ball game, and we wouldnโ€™t want to overwhelm you now, would we? ๐Ÿฅณ

Just remember: UTC is the name of the game, and consistency is the key to making friends (and databases) in high places. Happy dating, serializing, and time-traveling! ๐ŸŽ‰๐Ÿ•ฐ๏ธ๐Ÿš€

Enchanting Enum Magic! ๐Ÿง™โ€โ™‚๏ธ๐Ÿช„

Step right up, data sorcerers! Laravelโ€™s Eloquent isnโ€™t just a wand for querying databases; itโ€™s also a spellbook for PHP Enums! To cast your attribute values into these mystical entities, simply point your Modelโ€™s casts method towards the attribute and enum you wish to enchant:

use App\Enums\ServerStatus;

/**
 * Get the attributes that should be enchanted.
 *
 * @return array<string, string>
 */
protected function casts(): array
{
    return [
        'status' => ServerStatus::class,
    ];
}

Once youโ€™ve bestowed this magic upon your Model, the specified attribute will be transformed into an Enum whenever you conjure it up:

if ($server->status === ServerStatus::Provisioned) {
    $server->status = ServerStatus::Ready;

    // Abracadabra! The server is saved with its new status. ๐Ÿฆƒ
}

Remember, enchanting arrays of Enums is also possible! Hereโ€™s a spell for that:

use App\Enums\ServerStatus;

protected function casts(): array
{
    return [
        'statuses' => ServerStatus::class, // <-- Array of Enums here! ๐Ÿ“ฆ๐Ÿ”ฎ
    ];
}

Now, whenever you access or manipulate the statuses attribute, youโ€™ll be dealing with a delightfully enchanted array of Servers. Happy querying, sorcerers! ๐Ÿš€โœจ

Turning Your Array of Enums into a Comical Spectacle (Because Who Needs Boring, Right?)

Sometimes, your model might feel the urge to hold a riotous array of enum values in a single column, like a wild party crammed into a phone booth. To tame this chaos and bring order to the madness, Laravel offers two enchanting casts: AsEnumArrayObject and AsEnumCollection.

use App\Enums\ServerStatus;
use Illuminate\Database\Eloquent\Casts\AsEnumCollection;

/**
 * Get the attributes that should be transformed into something less chaotic.
 *
 * @return array<string, string>
 */
protected function casts(): array
{
    return [
        'statuses' => AsEnumCollection::of(ServerStatus::class), // Turns your array of enums into a well-behaved collection
        'chaos' => AsEnumArrayObject::of(DisarrayInThePhoneBooth::class) // Because every party needs a little bit of unexpected chaos!
    ];
}

P.S. The DisarrayInThePhoneBooth enum is not actually part of Laravel, but it would make for a fun addition, wouldnโ€™t it? ๐Ÿ˜‰

Cryptic Capers for Columns! ๐Ÿ”“๐Ÿš€

Ever had a sneaky suspicion that your data might be eavesdropped on by nosy neighbors? Fear not, Laravelโ€™s got your back with the Encrypted Cast! Itโ€™s like a secret decoder ring for your models, encrypting attribute values using our top-secret, built-in encryption technology.

Think of it as a superhero cape, turning plain Jane data into cryptic capers before tucking them away in your database. But like any good cape, itโ€™s got some quirks: the encrypted text is longer than its original and its final length isnโ€™t always predictable, so make sure your associated database column is as spacious as a grand ballroom (i.e., TEXT type or larger).

Since weโ€™re dealing with secret squirrel business here, you wonโ€™t be able to query or search encrypted attribute values like Sherlock Holmes would with his violin bow and magnifying glass ๐Ÿ•ต๏ธโ€โ™‚๏ธ. But hey, if itโ€™s good enough for James Bond, it should be good enough for your app!

Key Rotation Time! โณ๐Ÿ”‘

Now, remember that our cape isnโ€™t just one-size-fits-all. To keep those pesky data thieves on their toes, you can rotate the encryption key like a secret agent changing hideouts! Head on over to our key rotation guide for a step-by-step on how to pull off this tricky move. ๐Ÿ•ต๏ธโ€โ™‚๏ธ๐Ÿ”‘๐Ÿž๏ธ

Alrighty, buckle up, buttercup! Youโ€™re about to dive into the delightful world of key rotation in Laravel Land. Itโ€™s like swapping out the secret combination to your secret garden (but with more PHP and less sunburn).

Now, you probably already know that our beloved Laravel encrypts strings using the magical key value from your appโ€™s app.php configuration file. This key, my dear friends, is often the same as the value of your trusty APP_KEY environment variable (itโ€™s like theyโ€™re twins separated at birth).

But what happens when you need to change the locks on this secret garden? Well, thatโ€™s where our graceful key rotation comes into play! Itโ€™s not only a smoother way to rotate your keys but also a great opportunity to show off your new set of house keys to all your friends in the PHP community. (Seriously though, check out our documentation on gracefully rotating encryption keys for more details.)

Just remember: a key rotation is like a new haircut โ€“ itโ€™s good to keep things fresh and secure! ๐Ÿ”‘โœจ๐Ÿ’‡โ€โ™‚๏ธ

Time Travel with Query Casting!

Ever found yourself in a pickle, trying to make sense of raw data straight from the horseโ€™s mouth (er, database)? Worry not, my friend! Laravelโ€™s got your back with a feature thatโ€™ll have you feeling like Doc Brown in a DeLorean. Thatโ€™s right, weโ€™re talking about Query Time Casting!

Letโ€™s take a gander at this scenario:

use App\Models\Post;
use App\Models\User;

$users = User::select([
    'users.*',
    'last_posted_at' => Post::selectRaw('MAX(created_at)')
        ->whereColumn('user_id', 'users.id')
])->get();

Now, if you squint real hard at the results, you might notice that the last_posted_at attribute is as useful as a chocolate teapot โ€“ itโ€™s just a string! But fret not, for we can cast this into something more akin to a Swiss timepiece with the withCasts method:

$users = User::select([
    'users.*',
    'last_posted_at' => Post::selectRaw('MAX(created_at)')
        ->whereColumn('user_id', 'users.id')
])->withCasts([
    'last_posted_at' => 'datetime' // Boom! You just travelled back in time! ๐Ÿ•ฐ๏ธ๐Ÿš€
])->get();

And there you have it, my friend! Now you can make sense of those date stamps without needing a degree in chronology. Happy querying! ๐ŸŽ‰๐ŸŽ‰๐ŸŽ‰

Alrighty, Laravelโ€™s built-in cast types are a delightful buffet of handy helpers, but sometimes you might find yourself craving your own custom flavor. Fret not! To whip up a bespoke cast, just give the trusty Artisan command a shout:

php artisan make:cast AsJson

Your new cast class will find its home in app/Casts, ready to dazzle with its culinary skills.

Every custom cast class must don the hat of the CastsAttributes interface, and this dapper suit requires two essential methods: a getter (responsible for turning database raw values into a delectable cast form) and a setter (tasked with transforming your cast creation into a tasty morsel suitable for storage). Letโ€™s recreate the popular built-in json cast type as a custom concoction:

<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;

class AsJson implements CastsAttributes {
    // A little dance, a dash of PHP, and voila! We've got our custom cast type.

    public function get(
        Model $model,
        string $key,
        mixed $value,
        array $attributes
    ): array {
        return json_decode($value, true);
    }

    public function set(
        Model $model,
        string $key,
        mixed $value,
        array $attributes
    ): string {
        return json_encode($value);
    }
}

Once your custom cast type is cooked to perfection, attach it to a model attribute using its class name:

<?php

namespace App\Models;

use App\Casts\AsJson;
use Illuminate\Database\Eloquent\Model;

class User extends Model {
    // Time to set the table, and set it straight with our new custom cast.

    protected function casts(): array
    {
        return [
            'options' => AsJson::class,
        ];
    }
}

And there you have it! Your Laravel models are now ready to serve up the freshest and most flavorful custom casts around. Bon appรฉtit! ๐Ÿด๐Ÿฅ„๐ŸŽ‰

Alright, buckle up, Laravel cowpokes! Weโ€™re diving into the wild world of Value Object Casting โ€“ where your data isnโ€™t just numbers and strings anymore, but can now be as exciting as a grizzly bear in a honey jar! ๐Ÿป๐Ÿฏ

Youโ€™ve already been able to cast values to primitive types like a pro, but now weโ€™re kicking it up a notch by letting you cast them to objects! Imagine that โ€“ casting your data into an object as effortlessly as pouring whiskey into a tumbler. ๐Ÿฅƒ

Defining custom casts for objects is similar to the primitives, but thereโ€™s one important twist if your value object involves more than one column: The set method must return an array of key-value pairs that will be used to set raw, storable values on the model. If your object only affects a single column, you can simply return the storable value like a well-dressed cowboy walking into Dodge City.

Letโ€™s say we want to define a custom cast class that turns multiple model values into a sleek Address value object with properties lineOne and lineTwo. Weโ€™ll make some assumptions about our Address value object, which weโ€™ve named after an old-timey saloon:

<?php

namespace App\Casts;

use App\ValueObjects\Saloon as Address;
// ... (rest of the class)

Hereโ€™s a taste of what the code inside that class might look like:

public function get(
    Model $model,
    string $key,
    mixed $value,
    array $attributes,
): Address {
    return new Saloon($attributes['line_one_of_the_saloon'], $attributes['line_two_of_the_saloon']);
}

public function set(
    Model $model,
    string $key,
    mixed $value,
    array $attributes,
): array {
    // ... (rest of the code)
}

Casting to value objects is a piece of cake! Any changes you make to your value object will be automatically synced back to the model before it gets saved โ€“ just like how a cowboy might adjust his hat after dismounting from a horse. ๐ŸŽฉ

use App\Models\User;

$user = User::find(1);

$user->saloon->line_one_of_the_saloon = 'Updated Address Value';

$user->save();

[!NOTE] When youโ€™re planning to serialize your Eloquent models containing value objects into JSON or arrays, donโ€™t forget to implement the Illuminate\Contracts\Support\Arrayable and JsonSerializable interfaces on the value object. Itโ€™s as important as knowing how to rope a bronco! ๐ŸŽ๐ŸŒž

Cache-tastic Value Objects, Yโ€™all! ๐Ÿฅณ

In the wild world of Eloquent, when attributes turn into fancy value objects (like a chic pair of shoes or a witty one-liner), they get stashed away in the memory locker for later use. So, if you try to access that attribute again, instead of fetching it fresh off the database rack, Eloquent will hand you the very same object instance it saved earlier - talk about a fashion repeat! ๐Ÿ‘—

But what if youโ€™re feeling a little too cachy-cachy and want to break free from this memory locker? You can do just that by declaring a public withoutObjectCaching property in your custom cast class. Just think of it as the โ€˜Free Birdโ€™ of object caching - no more being tethered to the same instance! ๐ŸŽธ

class AsAddress implements CastsAttributes
{
    public bool $withoutObjectCaching = true; // It's showtime, Charlie!

    // ...
}

Now go forth and conquer those object caches with style! ๐Ÿค˜๐Ÿ’ƒ

Array / JSON Transmogrification (aka, Turning Laravel Models into Jokes and Back)

Ah, the magical world of Laravel Eloquent models! Where data transforms into arrays and JSON like Cinderella turning into a pumpkin at midnight - but way cooler. The toArray and toJson methods are your fairy godparents here, handling the transformation, and they wonโ€™t leave you high and dryโ€ฆ unless youโ€™re dealing with custom cast value objects from third-party libraries.

In such situations, adding the Illuminate\Contracts\Support\Arrayable and JsonSerializable interfaces to your object is like asking a wallflower to start a dance-off. So, we let our custom cast class take the lead! To do so, it needs to implement the Illuminate\Contracts\Database\Eloquent\SerializesCastableAttributes interface.

Think of this interface as the audition form for becoming the serenading swan of your value object transformation. Your custom cast class should impress with a serialize method, which, like a well-timed punchline, returns the serialized form of your value object:

/**
 * Discover the witty one-liner of the serialized representation of the value.
 *
 * @param  Model $model
 * @param  string $key
 * @param  mixed $value
 * @param  array $attributes
 */
public function serialize(
    Model $model,
    string $key,
    mixed $value,
    array $attributes,
): string {
    return (string) $value; // Transform the value into something you can laugh about
}

Now, letโ€™s talk about inbound casting - thatโ€™s when data from your JSON or array is transformed into an Eloquent model. Itโ€™s like a game of Telephone, but with more coding and less childhood nostalgia. When you want to handle this transformation manually, you can create a custom cast class that implements the Illuminate\Contracts\Database\Eloquent\CastsAttributes interface. This interface demands a get method, which is like a stand-up routine for your data - it should return the transformed value from your JSON or array:

/**
 * Transform the given value into a Eloquent model instance.
 *
 * @param  mixed $value
 * @param  string $key
 * @param  array $attributes
 */
public function get(
    Model $model,
    string $key,
    mixed $value,
    array $attributes,
): \Illuminate\Database\Eloquent\Model {
    // Transform the value into an Eloquent model instance here
}

And there you have it! Now youโ€™re ready to turn data into jokes and back again. Happy coding, comedians!

The One-Way Transformers Club

Sometimes, you might find yourself in a situation where you need to create a custom cast class that only works its magic when values are being bestowed upon the model. Think of it like a butler who polishes silverware before dinner but sleeps through breakfast.

To join this exclusive club, your cast should implement the CastsInboundAttributes interface, which, in true elite fashion, requires nothing more than a swanky set method. The make:cast Artisan command can be summoned with the --inbound option to create an invitation-only cast class:

php artisan make:cast AsHash --inbound

A perfect example of a one-way cast is a โ€œhashingโ€ cast. Imagine a case where we define a cast that hashes incoming values using a fancy algorithm, like a secret sauce for your data:

<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsInboundAttributes;
use Illuminate\Database\Eloquent\Model;

class AsHash implements CastsInboundAttributes
{
    /**
     * A grand entrance for new cast members.
     */
    public function __construct(protected ?string $algorithm = null) {}

    /**
     * Dress up before the party starts.
     *
     * @param  array<string, mixed>  $attributes
     */
    public function set(Model $model, string $key, mixed $value, array $attributes): string
    {
        // If no algorithm is provided, we'll default to the classic bcrypt method.
        if (is_null($this->algorithm)) {
            return bcrypt($value);
        }

        // But if an algorithm is provided, we'll hash it up with style!
        return hash($this->algorithm, $value);
    }
}

Cast Party Time!

Ready to throw a custom cast bash in Laravel-land? When you invite a model to the dance, donโ€™t forget to bring some party favors โ€“ those being cast parameters! To get everyone on the same page, separate them from your class name with a colon and commas. Multiple guests are welcome, just make sure they line up politely for the entrance:

/**
 * Find out who should get a makeover.
 *
 * @return array<string, string>
 */
protected function castParty(): array
{
    return [
        'secret' => 'AsHash::class'.':sha256', // Invite SHA-256 for a secret rendezvous!
    ];
}

Oh, and when it comes to comparing cast values, remember that theyโ€™re just like comparing dance moves โ€“ each one has its own groove. The constructor of the cast class will be the judge, making sure everyone gets a fair shake! ๐Ÿ•บ๏ธ๐ŸŽ‰

Custom Casting Magic: Making Your Models Feel Like Hogwartsโ€™ Potion Class! ๐Ÿ’ซ

Ever felt like your models were missing a dash of magic? Well, grab your wand (or your keyboard) and letโ€™s brew some custom casting potions! If you want Eloquent to understand when two values are brewed into the same magical elixir, then itโ€™s time to whip up a custom cast class. This spellbinding concoction will allow you to control which bewitched values Eloquent considers identical and thus saves to the database when your model undergoes a transformation (or an update).

To create your very own potion brewing apparatus, youโ€™ll need to conjure up a class that implements the Illuminate\Contracts\Database\Eloquent\ComparesCastableAttributes spellbook. This ancient tome grants you the power to decide which bewitched values are considered identical and worthy of saving in your database.

The spellbook demands your custom cast class to contain a compare incantation that returns true if the given brewed potions (or values) are indeed equal:

/**
 * Does this cauldron bubble or not?
 *
 * @param  \Illuminate\Database\Eloquent\Model $model The potion-making vessel
 * @param  string $key The magical ingredient we're brewing
 * @param  mixed $firstValue The initial brew
 * @param  mixed $secondValue The new brew
 * @return bool Is the new brew just a refill or a completely different potion?
 */
public function compare(
    Model $model,
    string $key,
    mixed $firstValue,
    mixed $secondValue
): bool {
    return $firstValue === $secondValue; // If it's the same brew, it must be magic!
}

Remember to always keep your spells in order and follow the rules of potion-making etiquette. Happy casting, my friends! ๐Ÿค“โœจ

Magical Beans! ๐Ÿช„๐ŸŒป

Ever wished your applicationโ€™s charm bracelets could transform into their own custom magical spells? Well, hold onto your broomsticks because we got just the potion for that! Instead of binding your model with a bewitched spell bottle, you can attach a magical bean class ๐ŸŒฑ that implements the Illuminate\Contracts\Database\Eloquent\Castable spellbook:

use Beans\MagicalAddress;

protected function brewPotions(): array
{
    return [
        'address' => MagicalAddress::class,
    ];
}

Beans that have learned the Castable spellbook must concoct a castUsing charm that reveals the name of their custom caster class responsible for brewing to and from magical potions:

<?php

namespace Beans;

use Illuminate\Contracts\Database\Eloquent\Castable;
use Potions\AsAddress;

class MagicalAddress implements Castable
{
    /**
     * Discover the name of the caster class to use when brewing from / to this cast target.
     *
     * @param  array<string, mixed> $ingredients
     */
    public static function brewUsing(array $ingredients): string
    {
        return AsAddress::class;
    }
}

When using Castable beans, you may still add ingredients to the brewPotions recipe. The ingredients will be passed to the brewUsing charm:

use Beans\MagicalAddress;

protected function brewPotions(): array
{
    return [
        'address' => MagicalAddress::class.':ingredient',
    ];
}

This section now named โ€œAnonymous Cast Classesโ€ instead of โ€œStatic Cast Classesโ€ for a more magical touch!

Anonymous Cast Classes ๐Ÿ‘ป

If youโ€™re feeling extra mystical, you can even conjure up your own anonymous cast classes on the fly! To do this, simply provide an anonymous function in the brewPotions method definition. The function will be called with the same arguments as the brewUsing charm:

use Closure;
use Beans\MagicalAddress;

protected function brewPotions(): array
{
    return [
        'address' => fn(Closure $ingredient) => MagicalAddress::class .':'. $ingredient(),
    ];
}

Alrighty then! Letโ€™s dive into the enchanting world of Castables and Anonymous Cast Classes โ€“ Laravelโ€™s magical solution to making your code as stylish as a runway model and as functional as a Swiss Army Knife.

Imagine combining a value object with PHPโ€™s secret sauce known as anonymous classes. Itโ€™s like merging a beautiful pearl necklace with a trusty multi-tool! The result? A single, stunning, castable object complete with its very own logic for casting spells โ€“ or in programming terms, data manipulation.

To create this sorcery, simply return an anonymous class from your value objectโ€™s castUsing method. This mysterious, unnamed class must obey the rules set forth by the CastsAttributes interface:

<?php

namespace App\ValueObjects;

// ... Importing necessary interfaces...

class Address implements Castable
{
    // ...

    /**
     * Call the casting covenant when we're changing from / to this cast target.
     *
     * @param  array<string, mixed>  $arguments
     */
    public static function castUsing(array $arguments): CastsAttributes
    {
        // Abracadabra! Introducing our anonymous casting helper...
        return new class implements CastsAttributes
        {
            // The spells this helper can perform...
            public function get(
                Model $model,
                string $key,
                mixed $value,
                array $attributes,
            ): Address
            {
                // Perform a spell to create a new Address object...
                return new Address(
                    $attributes['address_line_one'],
                    $attributes['address_line_two']
                );
            }

            public function set(
                Model $model,
                string $key,
                mixed $value,
                array $attributes,
            ): array
            {
                // Cast the incoming value into a usable format and return...
                return [
                    'address_line_one' => $value->lineOne,
                    'address_line_two' => $value->lineTwo,
                ];
            }
        };
    }
}

And there you have it! With this enchanting code, you can make your Address value object dance to the tune of Laravelโ€™s casting logic. Just remember โ€“ practice makes perfect, so keep practicing those spells!

Other Funny Docs

**Welcome to Laravel Land!** ๐ŸŒ„ # Collections ๐ŸŽ‰๐ŸŽฉ # Concurrent Chaos, or How to Make Your Computer Dance Simultaneously ๐Ÿ•บ๏ธ๐Ÿ’ƒ๏ธ # Controllers: The Gladiators of the Digital Colosseum ๐Ÿ† # Database: The Magical Scroll of Infinite Data! ๐Ÿง™โ€โ™‚๏ธ๐Ÿ“– # Eloquent: The Great Serialize-Off! ๐Ÿฅณ๐ŸŽ‰ # Eloquent: The Swanky Buffet of Data! ๐ŸŽ‰๐Ÿฝ๏ธ # Eloquent's Amorous Affairs: A Love Letter to Data Relations! # Hashbash 101: Laravel's Secret Sauce for Security! ๐Ÿ”’๐ŸŽ‰ # Laravel's Heart Monitor ๐Ÿ’ผ๐Ÿ•บ๏ธ # Laravel's Magical Deployment Genie: Envoy! ๐Ÿงžโ€โ™‚๏ธ๐ŸŽฉ # Laughter Logs ๐Ÿ˜ƒ # Locksmith Services: Laravel's Top-Secret Spy Kit ๐Ÿ”‘๐Ÿ•ต๏ธโ€โ™‚๏ธ # The Database Dance: A Laravel Ballroom Guide ๐Ÿ’ƒ๐Ÿป๐ŸŽ‰ # The Grand Ol' Setup! ๐ŸŽถ๐Ÿฅ # The Great File Adventure! ๐Ÿ“š ๐Ÿš€ # The Great Laravel Password Adventure # The Magnificent Mongoose's Guide to Storing Data in the Land of BSON! ๐Ÿฆ๐Ÿ“œ ๐Ÿ””๐Ÿ“ฃ **Attention All Developers!** A Journey Through Laravel's File System Jungle! ๐ŸŒณ๐Ÿ” Ahoy there, coders and jesters alike! Brace yourself for a thrilling journey through the fantastical realm of Laravel Strings - the magic ingredient that makes your apps talk to you like a wise old sage (or a chatty parrot, if you prefer). Ahoy there, database enthusiasts! Let's embark on a fantastical journey into the heart of Laravel's mystifying seed land! Yes, you heard it right โ€“ we're talking about Database Seeding! Ahoy there, intrepid coder! Set sail for a grand adventure with Laravel's swashbuckling documentation! ๐Ÿดโ€โ˜ ๏ธ Ahoy there, Laravel sailors! Buckle up for an exhilarating journey into the realm of Eloquent API Resources. This section is chock-full of goodies that'll make your RESTful dreams come true. Let's dive right in! ๐ŸŒŠ Ahoy there, matey! Buckle up for a whirlwind tour of Laravel's process management! This is where the magic happens, and by "magic," we mean command line sorcery. Ahoy, mateys! Sail the Laravel seas with us as we delve into the art of mockery - not the kind that makes people laugh (although that's always a plus), but the one that helps you write better tests. Ready to plunder treasures of knowledge? Let's set sail! Alright, let's dive into the hilarious world of Laravel Licensing! ๐ŸŽ ๐ŸŽช Alrighty, buckle up, coding cowboy (or cowgirl)! Let's dive into the wild west of Laravel deployment where we'll tame servers, tweak configurations, and optimize for speedier draw times. But first, a quick warning: this here is more than just roping cattle, so if you ain't familiar with server requirements, Nginx, FrankenPHP, or directory permissions, best hitch a ride on the documentation horse. Anchors Aweigh! Welcome to Laravel Sail! ๐Ÿšข๐Ÿš€ Console Chortles: The Laugh-and-Learn Guide ๐ŸŽค๏ธ Contracts: The Sworn Code of Laravel Land! ๐Ÿค๐Ÿ“œ Database: The Gateway to Data Nirvana ๐Ÿš€๐ŸŒŸ Database: The Quarry Master Database: Time Machine for Your Data Eloquent: The Magical Factory of Your Database Dreams! ๐Ÿงšโ€โ™‚๏ธ๐Ÿ› ๏ธ Eloquent: The Posh Puppy of PHP Database Frameworks! ๐Ÿถ Fancy Pants Shortcuts ๐Ÿคต๐Ÿ‘— Frontend Fun Times! ๐ŸŽ‰๐ŸŽˆ HTTP Hooligans: A Survival Guide for Web Shenanigans in Laravel Land! ๐Ÿค“ Laravel Cashier (Paddle): The Silicon Valley of Subscription Billing ๐Ÿš€โœจ Laravel Cashier: Your Buddy for Stripe Shenanigans! ๐Ÿ’ฐ๐Ÿ’ณ Laravel Dusk: The Web Browser Robot for Your Laravel App! ๐Ÿค– Laravel Flagship ๐Ÿณ๏ธโ€๐ŸŒˆ Laravel Forti-Fantastic! ๐ŸŽ‰๐Ÿฐ Laravel Mix: The Magical Elixir of Your Web Application's Happiness ๐Ÿฐ Laravel Octane: The Supercharged PHP Superhero! โšก๏ธ๐Ÿš€ Laravel Passport: The Magic Key to Your API Kingdom ๐Ÿ”‘โœจ Laravel Pint: Your Chill Buddy for Code Quality! ๐Ÿป Laravel Sanctum: Your Secret Weapon for API Security! ๐Ÿš€๐Ÿ›ก๏ธ Laravel Scout: The Sherlock of Databases! ๐Ÿ•ต๏ธโ€โ™‚๏ธ Laravel's AI Sidekick ๐Ÿš€๐Ÿค– Laravel's AI Time Machine ๐Ÿ•ฐ๏ธ๐Ÿš€ Laravel's Bag O' Tricks! Laravel's Dance Floor: A Symphony of Code! ๐ŸŽถ๐Ÿฅ Laravel's Magical Command-Line Puppeteer (MCP) โœจ๐ŸŽฉ Laravel's Magical Domain Whisperer: Valet! ๐Ÿง™โ€โ™‚๏ธ๐Ÿ”ฎ Laravel's Magical Homestead for Developers, Wizards, and Aliens! ๐Ÿก๐Ÿš€ Laravel's Magical, Shiny Socialite! ๐ŸŒˆโœจ Laravel's Shining Star: Horizon! ๐Ÿš€โœจ Laravel's Stargazing Gadget: Telescope! ๐Ÿ”ญ๐Ÿš€ Laravel's Swanky Navigation Guide! ๐Ÿ•บ๏ธ Laugh, Log, Love! ๐Ÿค– logging in Laravel ๐ŸŽ‰ Laugh, Test, Conquer: Your Laravel Guide to Fun-tastic Testing! ๐Ÿฅณ๐ŸŽ‰ Laughable Laravel HTTP Hilarity! ๐ŸŽญ๐Ÿ’ฌ Laughing at the Glitches: Laravel's Error Handling Guide! ๐Ÿ˜œ Laughter and Coding: A Journey to Laravel 13.0! (From the Stables of 12.x) Let's Chat Like Never Before with Laravel Broadcasting! ๐Ÿ—ฃ๏ธ๐ŸŽ™๏ธ Lingo-Magic: Make Your Laravel App Speak Every Language Under the Sun! ๐ŸŒ๐ŸŽ™๏ธ Middleware Mayhem! ๐Ÿ•น๏ธ๐Ÿฆธโ€โ™‚๏ธ Package Shenanigans! ๐ŸŽ‰๐Ÿฅณ Redis: The Swift, Silicon Superhero of Data Storage! ๐Ÿฆธโ€โ™‚๏ธ๐Ÿš€ Rockstar Rate Limiting ๐ŸŽธ๐Ÿฅ๐ŸŽ‰ Service Provider Shenanigans! ๐Ÿค˜ Temples of Data: Laravel's Views Temple (Don't worry, no incense required) The All-Knowing, Magic Bean of PHP Land! ๐Ÿช„๐Ÿš€ The Art of Email in Laravel Land! ๐Ÿ•ต๏ธโ€โ™‚๏ธ๐Ÿ’Œ The Art of Validation: A Laravel Masterclass! ๐ŸŽ‰๐ŸŽ“ The Artisan's Playground ๐Ÿง›โ€โ™‚๏ธ๐Ÿ”ฉ The Dance of Responses The Gatekeeper's Handbook (But Slightly More Entertaining) The Globetrotter's Guide to Laravel Sessions The Great Escape Act: Laravel's Magic Trick with Queues! The Great Interweb Explorer: Laravel's HTTP Client The Great Laravel Journey: A Comic Adventure! ๐ŸŽ‰๐Ÿš€ The Great Laravel Soiree: An Eventful Revelry! ๐ŸŽ‰๐ŸŽŠ The Incredible Journey of Email Verification! ๐Ÿš€๐Ÿ“ง The Incredible, Mysterious World of CSRF Protection! ๐Ÿฆนโ€โ™‚๏ธ๐Ÿ”’ The Joyful Symphony of Asset Bundling: Vite Edition! ๐ŸŽถ The Laravel Play-Doh Kit: Your Gateway to Fun and Fancy Web Development! ๐ŸŽจ๐ŸŒ The Magic Show of Laravel Lifecycle ๐ŸŽฉโœจ The Quest for Knowledge: A Laravel Adventure! ๐Ÿ“š๐Ÿš€ The Time Travelling Task Manager (TTTM) The Wild West of Web Navigation: Laravel's Routing! ๐Ÿค ๐ŸŽ  Time Travel, Laravel Style! ๐Ÿ”ฎโณ Title: **How to Contribute Like a Rockstar ๐ŸŽธ** Title: **Welcome to Laravel's Magical Terminal Tour!** ๐ŸŽช๐ŸŽง Unleash the Power of Cache! (Or, How to Speed Up Your App Without Breaking a Sweat) Unlocking the Kingdom! (aka, Authentication in Laravel) URL Navigation: The Cosmic Wayfarer's Guide to Cyberspace! ๐Ÿ›ธ๐Ÿš€ Welcome to Laravel Boost, the supercharger for your PHP applications! ๐Ÿš€๐Ÿ’จ Welcome to Laravel Land! ๐ŸŒด๐ŸŽ‰ Wickedly Wonderful Blade Templates! ๐Ÿง™โ€โ™‚๏ธ๐Ÿ”ฎ