How to write multiple expressions in PHP arrow functions
Asked Answered
T

5

35

How do you write a PHP arrow function with multiple line expressions?

JavaScript one-liner example:

const dob = (age) => 2021 - age;

PHP one-liner equivalent:

$dob = fn($age) => 2021 - $age;

Javascript multiple line example:

const dob = (age) => {
    if (!age) {
        return null;
    }
    const new_age = 2021 - age; 
    console.log("Your new age is " + new_age);
    return new_age;
}

What is the PHP equivalent for multiple lines within an arrow function?

Theresatherese answered 26/1, 2021 at 15:6 Comment(4)
What exactly are you asking? Just how to put the expression on a separate line, or to have multiple expressions? In PHP, you can only have one expression, but you can write it in multiple lines (as long as it's just a single expression, like your example of "multiple lines")Sophisticated
@MagnusEriksson I'm asking how to put multiple expressions or lines of code in an arrow function. I updated my question. If you understand the idea of an arrow function it will helpTheresatherese
I wish it was possible with PHP, but it's not. Only one line (expression) is allowed there.Hanover
The JavaScript example here is very god, I've came here as I was wondering how to log arrow function calls... Seems impossible.Alcohol
B
32

Arrow functions in PHP have the form fn (argument_list) => expr. You can only have a single expression in the body of the function.

You can write the expression over multiple lines without problem:

fn($age) =>
      $age
    ? 2021 - $age
    : null

If you really need multiple expressions, then you can simply use anonymous function. The closures aren't automatic as they are with arrow functions, but if you don't need it, it gives exactly the same result.

$dob = function ($age) {
    if (!$age) { return null; }
    $new_age = 2021 - ^$age; 
    echo "Your new age is ". $new_age;

    return $new_age;
}
Braxy answered 26/1, 2021 at 15:13 Comment(4)
This is still a single expression and not multiple. I updated my question.Theresatherese
@EmekaMbah I thought the first line of my answer was pretty clear: you can't have more than a single expression in the body of an arrow function in PHP. Just use a standard function for that.Braxy
Ok. Got it. Do you know if PHP plan to make this possible since single expression is not usually the caseTheresatherese
@EmekaMbah No, I haven't seen any RFC about this. But that's really not needed, especially if you don't need any capture like in your updated question: function ($age) { … } does the same thing than your JavaScript example.Braxy
A
10

The usage of multiple expressions is not allowed, according to the RFC. It covers the assignment of only a single expression. The extension is discussed further down in the RFC, but not implemented

Amphora answered 26/1, 2021 at 15:13 Comment(0)
I
0

There was some discussion in the PHP Internals mailing list regarding possible syntactic options for introducing the brevity and and data accessibility benefits of multiline arrow functions, but nothing gathered sufficient community support.

Until progress is made on that topic, your multi-line snippet can be written with a conditionally nested Immediately Invoked Functional Expression. My snippet will leverage the fact that when the passed-in age is not null, the returned value is expected to be an integer and it is therefore safe to multiply the calculated value by 1 (the return value of print). Otherwise,

Code: (Demo)

$name = 'mickmackusa';

$dob = fn(?int $age): ?int => !$age
    ? null
    : (
          fn($newAge) => $newAge * print "$name's age is $newAge\n" 
      )(2021 - $age);

var_export($dob(null));
echo "\n---\n";
var_export($dob(31));

Output:

NULL
---
mickmackusa's age is 1990
1990

Alternatively, use another ternary condition instead of multiplying.

Instal answered 8/2 at 21:10 Comment(0)
A
0
$getSquare = fn($num) => (function ($temp){
    echo "The square of $temp is : ";
    return $temp**2;
})($num);
echo $getSquare(10);
Arianna answered 5/7 at 14:49 Comment(2)
Then why even bother with arrow function here? ;)Sulphuric
@Sulphuric Its a hack for writing miltiline expression just like what we do in Javascript. This will also be helpful in match expression (newer version of switch case)Arianna
K
-2

You can use something like (expr1) && (expr2), for example:

$f = fn () => ($hasChanges = true) && ($this->comment = $operation->comment)

Note that expr1 must be true in any case, otherwise expr2 will not be executed.

If expr1 returns nothing (void) or falsy value, then wrap expr1 to (expr1 || true).

Kr answered 9/12, 2023 at 16:48 Comment(1)
The arrow function will return the boolean result of the evaluation, so this is not appropriate for the asked question.Instal

© 2022 - 2024 — McMap. All rights reserved.