DEV Community

spO0q
spO0q

Posted on

PHP 8.5: The Pipe Operator

The developer experience is far better in PHP 8 and later versions, for example, with Constructor property promotion.

When creating objects, such as DTOs, it saves time and energy.

I believe the new Pipe Operator of PHP 8.5 |> will bring the same kind of joy.

Chain callables

class Sanitizer {
    public static function removeAt(string $x): string {
        return str_replace('@', '', $x);
    }
    public function __invoke(string $x): string {
        return str_replace(' ', '-', $x);
    }
}

$value = " l@ l@ l@ ";
$sanitizedValue = $value
    |> 'trim'
    |> [Sanitizer::class, 'removeAt']
    |> (new Sanitizer());
Enter fullscreen mode Exit fullscreen mode

You may use the Pipe Operator with various callables from different sources, like built-in functions and custom helpers.

This will remove the hassle of typing the same intermediary variable again and again.

The return value of the previous expression is passed to the next callable which uses it as its first parameter.

Use your IDE

IMHO, it's best if you leverage your IDE to autocomplete or shortcut the pipe operator instead of typing it manually.

You may also use custom fonts (ligatures) to make it shine...

In any case, I find it more readable than the old (actually the current) way to chain callables.

It looks very natural.

Dealing with arrays

Usage with simple types, such as strings or integer, should be straightforward.

What about arrays?

$array = [
    ['specific' => ['a', 'b', 'c']],
    ['specific' => ['c', 'd', 'e']],
    ['specific' => ['x', 'y', 'c']],
];

$processedArray = $array
    |> fn($arr) => array_column($arr, 'specific')
    |> fn($arr) => array_merge(...$arr)
    |> array_unique(...)
    |> array_values(...);
Enter fullscreen mode Exit fullscreen mode

You may chain multiple functions quite the same way.

Current limitations

This new operator should cover common needs, but it's limited.

Only one argument?

All callable MUST accept only one required argument:

  • you cannot chain function with multiple required parameters (unless you provide fixed values)
  • you cannot chain function with no parameter

There are some RFCs on the topic, but it's delayed to PHP 8.6.

Can I use void?

void return types work, as long as you stay logical.

Because it does not return any value, it should be in the last position of the chain.

Otherwise, the next callables will receive null all the time.

Not the only way I can chain...

You might want to use nested functions instead:

$sanitizedValue = ucfirst(trim(str_replace('@', '', $value)));
Enter fullscreen mode Exit fullscreen mode

Not only that it's prone to errors (e.g., bad parenthesis), but it's significantly harder to read.

The pipe operator looks safer.

Usage with ternaries and other operators

Meh!

I've read examples where the piped operator gets combined with ternaries or the null coalescing operator ??.

As long as you know what you're doing, no problem.

However, ternaries are often bad for readability and the pipe operator has lower precedence over other operators, which might lead to unexpected errors if you don't add the right parenthesis.

Wrap this up

Another great tool inspired by the functional Universe.

Top comments (0)