artem_ml15 May 2026 10:10

Started using |> in a new service class and kept getting “Fatal error: Arrow functions on the right hand side of |> must be parenthesized”. Took longer than I want to admit to understand what was happening.

The rule: named functions and first-class callables do not need parentheses on the right side of |>. Arrow functions do. So $x |> trim(...) works, but $x |> fn($v) => trim($v) is a fatal error. You need $x |> (fn($v) => trim($v)).

PHP
<?php
$value = " hello world ";
// OK: first-class callable
$result = $value |> trim(...) |> strtoupper(...);
// Fatal error, missing parens:
// $result = $value |> fn($v) => strtolower(trim($v));
// Correct:
$result = $value |> (fn($v) => strtolower(trim($v)));
echo $result;
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Once you know the rule it makes sense since the parser needs to know where the arrow function ends. But the error message is not helpful for something this easy to get wrong.

Replies (4)
nphp15 May 2026 10:52

The error message really should say something like “did you forget parentheses around the arrow function?” instead of just the technical description. I hit the same wall when I first tried pipe operator in a side project.

0
fredbauer15 May 2026 11:25

This is actually how most languages with pipe operators handle it. In Elixir you would also need to wrap anonymous functions. The first-class callable syntax trim(...) is the more idiomatic way to use |> anyway once you get used to it. If you need a transform that does not have a name, that is a signal it might deserve one.

0
simondev15 May 2026 12:20

Agreed. For long chains, arrow functions in the middle hurt readability more than they help. The whole point of pipe is to read left-to-right. Something like $val |> sanitize(...) |> validate(...) |> format(...) is much clearer than mixing in |> (fn($v) => ...) every other step.

0
artem_ml15 May 2026 13:30

@simondev that is where I landed too. Started writing short private methods and using first-class callables for everything in the pipeline. The arrow function form is only worth it for truly trivial one-off transforms where a named method would be overkill.

0
Write a reply
Markdown. ```php blocks are runnable.