3

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
miken32
  • 42,008
  • 16
  • 111
  • 154

1 Answers1

3

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
htmlspecialchars(
    "Some text & stuff",
    ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401,
    null,
    false
);

But with named arguments it looks like this:

<?php
htmlspecialchars(
    "Some text & stuff",
    double_encode: false
);
miken32
  • 42,008
  • 16
  • 111
  • 154
  • The example the OP gives uses a different advantage of named parameters: you don't have to remember the *order* of parameters. The code shown clearly labels one callback as the getter and the other as the setter, without having to know which comes first in the signature of `Attribute::make`. Constructors and factories are a common use for this, as they often accept multiple arguments which are just being saved for later, and have no natural sequence. – IMSoP Apr 28 '22 at 10:25
  • Yeah that's not a bad point. I use an IDE that tells me those sorts of things so it wasn't something that came to mind. Of course, you still have to know the names of the arguments to use them... – miken32 Apr 28 '22 at 15:21
  • 1
    Yes, IDE labels and auto-complete serve a lot of the same purpose, but in a less standardised way. As for needing to know the names, that's true, but you'll get immediate feedback if you get them wrong, which you don't if you muddle positional parameters of the same type. More importantly, code is read many more times than it is written, and you don't need to consult the signature to *read* the parameter names. That's a huge win if the values don't provide much context - a really common example is boolean flags. – IMSoP Apr 28 '22 at 15:37
  • Yes, the documentation aspect is a really good point. Updated my answer accordingly. – miken32 Apr 28 '22 at 15:47
  • First I'm learning today about named arguments and then that arrow functions are possible in PHP, just because I stumbled about mentioned lines in the Laravel docs. I visited the PHP docs a lot of times. Why is the "fn" keyword not mentioned more often? – JackLeEmmerdeur Mar 20 '23 at 21:55