Skip to content

Commit 2946c8a

Browse files
authored
Document the pipe operator. (#4890)
1 parent 00a8ae0 commit 2946c8a

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

language/operators.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
&language.operators.string;
4343
&language.operators.array;
4444
&language.operators.type;
45+
&language.operators.functional;
4546

4647
</chapter>
4748
<!-- Keep this comment at the end of the file

language/operators/functional.xml

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<sect1 xml:id="language.operators.functional">
3+
<title>Functional Operators</title>
4+
<titleabbrev>Functional</titleabbrev>
5+
<para>
6+
PHP 8.5 and later supports one operator that works directly on callables. The <literal>|></literal>
7+
operator, or “pipe,” accepts a single-parameter callable on the right and passes
8+
the left-side value to it, evaluating to the callable's result. The callable
9+
on the right may be any valid PHP callable: a <classname>Closure</classname>,
10+
a <link linkend="functions.first_class_callable_syntax">first-class callable</link>,
11+
an object that implements <link linkend="object.invoke">__invoke()</link>, etc.
12+
</para>
13+
<para>
14+
That means the following two lines are logically equivalent.
15+
<example>
16+
<title>Using <literal>|></literal></title>
17+
<programlisting role="php">
18+
<![CDATA[
19+
<?php
20+
$result = "Hello World" |> strlen(...);
21+
print $result . PHP_EOL;
22+
23+
$result = strlen("Hello World");
24+
print $result . PHP_EOL;
25+
?>
26+
]]>
27+
</programlisting>
28+
&example.outputs;
29+
<screen>
30+
<![CDATA[
31+
11
32+
11
33+
]]>
34+
</screen>
35+
</example>
36+
</para>
37+
<para>
38+
For a single call that is not especially useful. It becomes useful when multiple calls are chained together.
39+
That is, the following two code fragments are logically equivalent:
40+
<example>
41+
<title>Chaining |> calls</title>
42+
<programlisting role="php">
43+
<![CDATA[
44+
<?php
45+
$result = "PHP Rocks"
46+
|> htmlentities(...)
47+
|> str_split(...)
48+
|> (fn($x) => array_map(strtoupper(...), $x))
49+
|> (fn($x) => array_filter($x, fn($v) => $v != 'O'))
50+
;
51+
print $result . PHP_EOL;
52+
53+
$temp = "PHP Rocks";
54+
$temp = htmlentities($temp);
55+
$temp = str_split($temp);
56+
$temp = array_map(strtoupper(...), $temp);
57+
$temp = array_filter($temp, fn($v) => $v != 'O');
58+
$result = $temp;
59+
print $result . PHP_EOL;
60+
?>
61+
]]>
62+
</programlisting>
63+
&example.outputs;
64+
<screen>
65+
<![CDATA[
66+
Array
67+
(
68+
[0] => P
69+
[1] => H
70+
[2] => P
71+
[3] =>
72+
[4] => R
73+
[6] => C
74+
[7] => K
75+
[8] => S
76+
)
77+
Array
78+
(
79+
[0] => P
80+
[1] => H
81+
[2] => P
82+
[3] =>
83+
[4] => R
84+
[6] => C
85+
[7] => K
86+
[8] => S
87+
)
88+
]]>
89+
</screen>
90+
</example>
91+
</para>
92+
<para>
93+
The left-hand side of the pipe may be any value or expression. The right-hand side
94+
may be any valid PHP callable that takes a single parameter, or any expression
95+
that evaluates to such a callable. Functions with more than one required parameter
96+
are not allowed and will fail as if the function were called normally
97+
with insufficient arguments. Functions that take a variable by reference are not allowed.
98+
If the right-hand side does not evaluate to a valid callable it will throw an Error.
99+
</para>
100+
<note>
101+
<para>
102+
Be aware that, to avoid syntax ambiguity, <link linkend="functions.arrow">arrow functions</link>
103+
MUST be wrapped in parentheses when used with a pipe operator, as in the examples above.
104+
Failing to do so will result in a fatal error.
105+
</para>
106+
</note>
107+
108+
<sect2 role="seealso">
109+
&reftitle.seealso;
110+
<para>
111+
<simplelist>
112+
<member><classname>Closure</classname></member>
113+
</simplelist>
114+
</para>
115+
</sect2>
116+
</sect1>

0 commit comments

Comments
 (0)