phplaravelphp-8laravel-9mutators

Laravel 9 mutators colon


In Laravel 9, there’s a different implementation for mutators. The following example is from the official documentation.

protected function firstName(): Attribute
{
    return Attribute::make(
        get: fn ($value) => ucfirst($value),
        set: fn ($value) => strtolower($value),
    );
}

But what is the colon: after get and set? Is this a new feature in PHP 8? The definition of Attribute::make is:

public static function make(callable $get = null, callable $set = null): Attribute

Solution

  • Named arguments are a new feature in PHP 8.0.

    In functions or methods with simple signatures it can serve as a sort of self-documentation to indicate what the arguments are. For example in the code you provided, both arguments are simple callbacks that perform basic string manipulation on the provided value. Without the argument names, someone reading the code would need to check the method signature to know what each argument does.

    It’s also a convenient way to only specify needed arguments when using functions or methods with long signatures or complex default values.

    For example, the signature for htmlspecialchars() looks like this:

    htmlspecialchars(
        string $string,
        int $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401,
        ?string $encoding = null,
        bool $double_encode = true
    ): string
    

    In previous versions if you wanted to change the double_encode argument to false, but leave the other arguments as default, you’d have to do this:

    <?php
    $escaped = htmlspecialchars(
        "Some text & stuff",
        ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401,
        null,
        false
    );
    

    In addition to being more cluttered, we're left with non-intuitive values like null and false. A typical approach in the past was to use variables for the values such as $is_double_encoded = false. But with named arguments it looks like this:

    <?php
    $escaped = htmlspecialchars(
        "Some text & stuff",
        double_encode: false
    );
    

    Not only do we skip the parameters which keep their default value, but the double_encode parameter is clearly labelled with its name, from which we can infer its usage.