language/functions.xml
dd87866772c31671146ff778140dc0955c55005c
dd87866772c31671146ff778140dc0955c55005c
...
...
@@ -7,12 +7,14 @@
7
7
<title>User-defined functions</title>
8
8
9
9
<para>
10
-
A function may be defined using syntax such as the following:
10
+
A function is defined using the <literal>function</literal> keyword,
11
+
a name, a list of parameters (which might be empty) seperated by commas
12
+
(<literal>,</literal>) enclosed in parentheses, followed by the body of
13
+
the function enclosed in curly braces, such as the following:
11
14
</para>
12
-
<para>
13
-
<example>
14
-
<title>Pseudo code to demonstrate function uses</title>
15
-
<programlisting role="php">
15
+
<example>
16
+
<title>Declaring a new function named <literal>foo</literal></title>
17
+
<programlisting role="php">
16
18
<![CDATA[
17
19
<?php
18
20
function foo($arg_1, $arg_2, /* ..., */ $arg_n)
...
...
@@ -22,12 +24,25 @@ function foo($arg_1, $arg_2, /* ..., */ $arg_n)
22
24
}
23
25
?>
24
26
]]>
25
-
</programlisting>
26
-
</example>
27
-
</para>
27
+
</programlisting>
28
+
</example>
29
+
<note>
30
+
<para>
31
+
As of PHP 8.0.0, the list of parameters may have a trailing comma:
32
+
<informalexample>
33
+
<programlisting role="php">
34
+
<![CDATA[
35
+
<?php
36
+
function foo($arg_1, $arg_2,) { }
37
+
?>
38
+
]]>
39
+
</programlisting>
40
+
</informalexample>
41
+
</para>
42
+
</note>
28
43
29
44
<simpara>
30
-
Any valid PHP code may appear inside a function, even other
45
+
Any valid PHP code may appear inside the body of a function, even other
31
46
functions and <link linkend="language.oop5.basic.class">class</link>
32
47
definitions.
33
48
</simpara>
...
...
@@ -170,14 +185,18 @@ function recursion($a)
170
185
</sect1>
171
186
172
187
<sect1 xml:id="functions.arguments">
173
-
<title>Function arguments</title>
188
+
<title>Function parameters and arguments</title>
174
189
175
190
<simpara>
191
+
The function parameters are declared in the function signature.
176
192
Information may be passed to functions via the argument list,
177
193
which is a comma-delimited list of expressions. The arguments are
178
-
evaluated from left to right.
194
+
evaluated from left to right and the result is assigned to the parameters of
195
+
the function, before the function is actually called
196
+
(<emphasis>eager</emphasis> evaluation).
179
197
</simpara>
180
198
199
+
<!-- Note: this paragraph feels like it should be moved to the syntax part? -->
181
200
<para>
182
201
PHP supports passing arguments by value (the default), <link
183
202
linkend="functions.arguments.by-reference">passing by
...
...
@@ -187,28 +206,32 @@ function recursion($a)
187
206
argument lists</link> and <link linkend="functions.named-arguments">Named Arguments</link>
188
207
are also supported.
189
208
</para>
190
-
<para>
191
-
<example>
192
-
<title>Passing arrays to functions</title>
193
-
<programlisting role="php">
209
+
<note>
210
+
<para>
211
+
As of PHP 7.3.0, it is possible to have a trailing comma in the argument
212
+
list for a function calls:
213
+
<informalexample>
214
+
<programlisting role="php">
194
215
<![CDATA[
195
216
<?php
196
-
function takes_array($input)
197
-
{
198
-
echo "$input[0] + $input[1] = ", $input[0]+$input[1];
199
-
}
217
+
$v = foo(
218
+
$arg_1,
219
+
$arg_2,
220
+
);
200
221
?>
201
222
]]>
202
-
</programlisting>
203
-
</example>
204
-
</para>
223
+
</programlisting>
224
+
</informalexample>
225
+
</para>
226
+
</note>
227
+
205
228
<para>
206
-
As of PHP 8.0.0, the list of function arguments may include a trailing comma, which
207
-
will be ignored. That is particularly useful in cases where the list of arguments is
208
-
long or contains long variable names, making it convenient to list arguments vertically.
229
+
As of PHP 8.0.0, the list of function parameters may include a trailing comma, which
230
+
will be ignored. That is particularly useful in cases where the list of parameters is
231
+
long or contains long variable names, making it convenient to list parameters vertically.
209
232
</para>
210
233
<example>
211
-
<title>Function Argument List with trailing Comma</title>
234
+
<title>Function parameter list with trailing comma</title>
212
235
<programlisting role="php">
213
236
<![CDATA[
214
237
<?php
...
...
@@ -223,28 +246,6 @@ function takes_many_args(
223
246
// ...
224
247
}
225
248
?>
226
-
]]>
227
-
</programlisting>
228
-
</example>
229
-
<para>
230
-
As of PHP 8.0.0, passing mandatory arguments after optional arguments
231
-
is deprecated. This can generally be resolved by dropping the default value.
232
-
One exception to this rule are arguments of the form
233
-
<code>Type $param = null</code>, where the &null; default makes the type implicitly
234
-
nullable. This usage remains allowed, though it is recommended to use an
235
-
explicit nullable type instead.
236
-
</para>
237
-
<example>
238
-
<title>Passing optional arguments after mandatory arguments</title>
239
-
<programlisting role="php">
240
-
<![CDATA[
241
-
<?php
242
-
function foo($a = [], $b) {} // Before
243
-
function foo($a, $b) {} // After
244
-
245
-
function bar(A $a = null, $b) {} // Still allowed
246
-
function bar(?A $a, $b) {} // Recommended
247
-
?>
248
249
]]>
249
250
</programlisting>
250
251
</example>
...
...
@@ -260,11 +261,11 @@ function bar(?A $a, $b) {} // Recommended
260
261
</simpara>
261
262
<para>
262
263
To have an argument to a function always passed by reference, prepend an
263
-
ampersand (&) to the argument name in the function definition:
264
+
ampersand (&) to the parameter name in the function definition:
264
265
</para>
265
266
<para>
266
267
<example>
267
-
<title>Passing function parameters by reference</title>
268
+
<title>Passing function arguments by reference</title>
268
269
<programlisting role="php">
269
270
<![CDATA[
270
271
<?php
...
...
@@ -281,15 +282,18 @@ echo $str; // outputs 'This is a string, and something extra.'
281
282
</example>
282
283
</para>
283
284
<para>
284
-
It is an error to pass a value as argument which is supposed to be passed by reference.
285
+
It is an error to pass a constant expression as an argument to a parameter
286
+
that expects to be passed by reference.
285
287
</para>
286
288
</sect2>
287
289
<sect2 xml:id="functions.arguments.default">
288
-
<title>Default argument values</title>
290
+
<title>Default parameter values</title>
289
291
290
292
<para>
291
-
A function may define C++-style default values for scalar
292
-
arguments as follows:
293
+
A function may define default values for parameters using syntax similar
294
+
to assigning a variable. The default is used only when the parameter's argument is
295
+
not passed. Note that passing &null; does <emphasis>not</emphasis>
296
+
assign the default value.
293
297
</para>
294
298
<para>
295
299
<example>
...
...
@@ -318,8 +322,9 @@ Making a cup of espresso.
318
322
</example>
319
323
</para>
320
324
<para>
321
-
PHP also allows the use of <type>array</type>s and the special type &null;
322
-
as default values, for example:
325
+
Default parameter values may be scalar values, <type>array</type>s,
326
+
the special type &null;, and as of PHP 8.1.0, objects using the
327
+
<link linkend="language.oop5.basic.new">new ClassName()</link> syntax.
323
328
</para>
324
329
<para>
325
330
<example>
...
...
@@ -333,43 +338,82 @@ function makecoffee($types = array("cappuccino"), $coffeeMaker = NULL)
333
338
return "Making a cup of ".join(", ", $types)." with $device.\n";
334
339
}
335
340
echo makecoffee();
336
-
echo makecoffee(array("cappuccino", "lavazza"), "teapot");
337
-
?>
341
+
echo makecoffee(array("cappuccino", "lavazza"), "teapot");?>
338
342
]]>
339
343
</programlisting>
344
+
&example.outputs;
345
+
<screen>
346
+
<![CDATA[
347
+
Making a cup of cappuccino with hands.
348
+
Making a cup of cappuccino, lavazza with teapot.
349
+
]]>
350
+
</screen>
340
351
</example>
352
+
</para>
353
+
<para>
354
+
<example>
355
+
<title>Using objects as default values (as of PHP 8.1.0)</title>
356
+
<programlisting role="php">
357
+
<![CDATA[
358
+
<?php
359
+
class DefaultCoffeeMaker {
360
+
public function brew() {
361
+
return "Making coffee.\n";
362
+
}
363
+
}
364
+
class FancyCoffeeMaker {
365
+
public function brew() {
366
+
return "Crafting a beautiful coffee just for you.\n";
367
+
}
368
+
}
369
+
function makecoffee($coffeeMaker = new DefaultCoffeeMaker)
370
+
{
371
+
return $coffeeMaker->brew();
372
+
}
373
+
echo makecoffee();
374
+
echo makecoffee(new FancyCoffeeMaker);
375
+
?>
376
+
]]>
377
+
</programlisting>
341
378
379
+
&example.outputs;
380
+
<screen>
381
+
<![CDATA[
382
+
Making coffee.
383
+
Crafting a beautiful coffee just for you.
384
+
]]>
385
+
</screen>
386
+
</example>
342
387
</para>
343
388
<simpara>
344
389
The default value must be a constant expression, not (for
345
390
example) a variable, a class member or a function call.
346
391
</simpara>
347
392
<para>
348
-
Note that when using default arguments, any defaults should be on
349
-
the right side of any non-default arguments; otherwise, things
350
-
will not work as expected. Consider the following code snippet:
393
+
Note that any optional parameters should be specified after any
394
+
required parameters, otherwise they cannot be omitted from calls.
395
+
Consider the following example:
351
396
</para>
352
397
<para>
353
398
<example>
354
-
<title>Incorrect usage of default function arguments</title>
399
+
<title>Incorrect usage of default function parameters</title>
355
400
<programlisting role="php">
356
401
<![CDATA[
357
402
<?php
358
-
function makeyogurt($type = "acidophilus", $flavour)
403
+
function makeyogurt($container = "bowl", $flavour)
359
404
{
360
-
return "Making a bowl of $type $flavour.\n";
405
+
return "Making a $container of $flavour yogurt.\n";
361
406
}
362
407
363
-
echo makeyogurt("raspberry"); // won't work as expected
408
+
echo makeyogurt("raspberry"); // "raspberry" is $container, not $flavour
364
409
?>
365
410
]]>
366
411
</programlisting>
367
412
&example.outputs;
368
413
<screen>
369
414
<![CDATA[
370
-
Warning: Missing argument 2 in call to makeyogurt() in
371
-
/usr/local/etc/httpd/htdocs/phptest/functest.html on line 41
372
-
Making a bowl of raspberry .
415
+
Fatal error: Uncaught ArgumentCountError: Too few arguments
416
+
to function makeyogurt(), 1 passed in example.php on line 42
373
417
]]>
374
418
</screen>
375
419
</example>
...
...
@@ -379,30 +423,93 @@ Making a bowl of raspberry .
379
423
</para>
380
424
<para>
381
425
<example>
382
-
<title>Correct usage of default function arguments</title>
426
+
<title>Correct usage of default function parameters</title>
427
+
<programlisting role="php">
428
+
<![CDATA[
429
+
<?php
430
+
function makeyogurt($flavour, $container = "bowl")
431
+
{
432
+
return "Making a $container of $flavour yogurt.\n";
433
+
}
434
+
435
+
echo makeyogurt("raspberry"); // "raspberry" is $flavour
436
+
?>
437
+
]]>
438
+
</programlisting>
439
+
&example.outputs;
440
+
<screen>
441
+
<![CDATA[
442
+
Making a bowl of raspberry yogurt.
443
+
]]>
444
+
</screen>
445
+
</example>
446
+
</para>
447
+
<para>
448
+
As of PHP 8.0.0, <link linkend="functions.named-arguments">named arguments</link>
449
+
can be used to skip over multiple optional parameters.
450
+
</para>
451
+
<para>
452
+
<example>
453
+
<title>Correct usage of default function parameters</title>
383
454
<programlisting role="php">
384
455
<![CDATA[
385
456
<?php
386
-
function makeyogurt($flavour, $type = "acidophilus")
457
+
function makeyogurt($container = "bowl", $flavour = "raspberry", $style = "Greek")
387
458
{
388
-
return "Making a bowl of $type $flavour.\n";
459
+
return "Making a $container of $flavour $style yogurt.\n";
389
460
}
390
461
391
-
echo makeyogurt("raspberry"); // works as expected
462
+
echo makeyogurt(style: "natural");
392
463
?>
393
464
]]>
394
465
</programlisting>
395
466
&example.outputs;
396
467
<screen>
397
468
<![CDATA[
398
-
Making a bowl of acidophilus raspberry.
469
+
Making a bowl of raspberry natural yogurt.
399
470
]]>
400
471
</screen>
401
472
</example>
402
473
</para>
474
+
<para>
475
+
As of PHP 8.0.0, declaring mandatory parameters after optional parameters
476
+
is <emphasis>deprecated</emphasis>. This can generally be resolved by
477
+
dropping the default value, since it will never be used.
478
+
One exception to this rule are parameters of the form
479
+
<code>Type $param = null</code>, where the &null; default makes the type implicitly
480
+
nullable. This usage is deprecated as of PHP 8.4.0, and an explicit
481
+
<link linkend="language.types.declarations.nullable">nullable type</link>
482
+
should be used instead.
483
+
<example>
484
+
<title>Declaring optional parameters after mandatory parameters</title>
485
+
<programlisting role="php">
486
+
<![CDATA[
487
+
<?php
488
+
489
+
function foo($a = [], $b) {} // Default not used; deprecated as of PHP 8.0.0
490
+
function foo($a, $b) {} // Functionally equivalent, no deprecation notice
491
+
492
+
function bar(A $a = null, $b) {} // As of PHP 8.1.0, $a is implicitly required
493
+
// (because it comes before the required one),
494
+
// but implicitly nullable (deprecated as of PHP 8.4.0),
495
+
// because the default parameter value is null
496
+
function bar(?A $a, $b) {} // Recommended
497
+
498
+
?>
499
+
]]>
500
+
</programlisting>
501
+
</example>
502
+
</para>
403
503
<note>
404
504
<simpara>
405
-
Arguments that are passed by reference may have a default value.
505
+
As of PHP 7.1.0, omitting a parameter which does not specify a default
506
+
throws an <classname>ArgumentCountError</classname>; in previous versions
507
+
it raised a Warning.
508
+
</simpara>
509
+
</note>
510
+
<note>
511
+
<simpara>
512
+
Parameters that expect the argument by reference may have a default value.
406
513
</simpara>
407
514
</note>
408
515
</sect2>
...
...
@@ -416,22 +523,11 @@ Making a bowl of acidophilus raspberry.
416
523
<literal>...</literal> token.
417
524
</simpara>
418
525
419
-
<note>
420
-
<simpara>
421
-
It is also possible to achieve variable-length arguments by using
422
-
<function>func_num_args</function>,
423
-
<function>func_get_arg</function>, and
424
-
<function>func_get_args</function> functions.
425
-
This technique is not recommended as it was used prior to the introduction
426
-
of the <literal>...</literal> token.
427
-
</simpara>
428
-
</note>
429
-
430
526
<para>
431
-
Argument lists may include the
527
+
Parameter lists may include the
432
528
<literal>...</literal> token to denote that the function accepts a
433
529
variable number of arguments. The arguments will be passed into the
434
-
given variable as an array; for example:
530
+
given variable as an &array;:
435
531
436
532
<example>
437
533
<title>Using <literal>...</literal> to access variable arguments</title>
...
...
@@ -491,7 +587,7 @@ echo add(...$a);
491
587
</para>
492
588
493
589
<para>
494
-
You may specify normal positional arguments before the
590
+
You may specify normal positional parameters before the
495
591
<literal>...</literal> token. In this case, only the trailing arguments
496
592
that don't match a positional argument will be added to the array
497
593
generated by <literal>...</literal>.
...
...
@@ -501,7 +597,7 @@ echo add(...$a);
501
597
It is also possible to add a
502
598
<link linkend="language.types.declarations">type declaration</link> before the
503
599
<literal>...</literal> token. If this is present, then all arguments
504
-
captured by <literal>...</literal> must be objects of the hinted class.
600
+
captured by <literal>...</literal> must match that parameter type.
505
601
506
602
<example>
507
603
<title>Type declared variable arguments</title>
...
...
@@ -542,46 +638,6 @@ Catchable fatal error: Argument 2 passed to total_intervals() must be an instanc
542
638
(<literal>&</literal>).
543
639
</para>
544
640
545
-
<sect3 xml:id="functions.variable-arg-list.old">
546
-
<title>Older versions of PHP</title>
547
-
548
-
<para>
549
-
No special syntax is required to note that a function is variadic;
550
-
however access to the function's arguments must use
551
-
<function>func_num_args</function>, <function>func_get_arg</function>
552
-
and <function>func_get_args</function>.
553
-
</para>
554
-
555
-
<para>
556
-
The first example above would be implemented as follows in old versions of PHP:
557
-
558
-
<example>
559
-
<title>Accessing variable arguments in old PHP versions</title>
560
-
<programlisting role="php">
561
-
<![CDATA[
562
-
<?php
563
-
function sum() {
564
-
$acc = 0;
565
-
foreach (func_get_args() as $n) {
566
-
$acc += $n;
567
-
}
568
-
return $acc;
569
-
}
570
-
571
-
echo sum(1, 2, 3, 4);
572
-
?>
573
-
]]>
574
-
</programlisting>
575
-
&example.outputs;
576
-
<screen>
577
-
<![CDATA[
578
-
10
579
-
]]>
580
-
</screen>
581
-
</example>
582
-
</para>
583
-
</sect3>
584
-
585
641
</sect2>
586
642
587
643
<sect2 xml:id="functions.named-arguments">
...
...
@@ -605,7 +661,7 @@ echo sum(1, 2, 3, 4);
605
661
<example>
606
662
<title>Named argument syntax</title>
607
663
<programlisting role="php">
608
-
<![CDATA[
664
+
<![CDATA[
609
665
<?php
610
666
myFunction(paramName: $value);
611
667
array_foobar(array: $value);
...
...
@@ -620,7 +676,7 @@ function_name($variableStoringParamName: $value);
620
676
<example>
621
677
<title>Positional arguments versus named arguments</title>
622
678
<programlisting role="php">
623
-
<![CDATA[
679
+
<![CDATA[
624
680
<?php
625
681
// Using positional arguments:
626
682
array_fill(0, 100, 50);
...
...
@@ -639,9 +695,9 @@ array_fill(start_index: 0, count: 100, value: 50);
639
695
<example>
640
696
<title>Same example as above with a different order of parameters</title>
641
697
<programlisting role="php">
642
-
<![CDATA[
698
+
<![CDATA[
643
699
<?php
644
-
array_fill(value: 50, num: 100, start_index: 0);
700
+
array_fill(value: 50, count: 100, start_index: 0);
645
701
?>
646
702
]]>
647
703
</programlisting>
...
...
@@ -657,31 +713,58 @@ array_fill(value: 50, num: 100, start_index: 0);
657
713
<example>
658
714
<title>Combining named arguments with positional arguments</title>
659
715
<programlisting role="php">
660
-
<![CDATA[
716
+
<![CDATA[
661
717
<?php
662
718
htmlspecialchars($string, double_encode: false);
663
719
// Same as
664
-
htmlspecialchars($string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
720
+
htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, 'UTF-8', false);
665
721
?>
666
722
]]>
667
723
</programlisting>
668
724
</example>
669
725
670
726
<para>
671
-
Passing the same parameter multiple times results in an Error exception.
727
+
Passing an argument to the same named parameter multiple times results in an
728
+
<classname>Error</classname> exception.
672
729
</para>
673
730
674
731
<example>
675
-
<title>Error exception when passing the same parameter multiple times</title>
732
+
<title>Error thrown when passing an argument to the same named parameter multiple times</title>
676
733
<programlisting role="php">
677
-
<![CDATA[
734
+
<![CDATA[
678
735
<?php
736
+
679
737
function foo($param) { ... }
680
738
681
739
foo(param: 1, param: 2);
682
740
// Error: Named parameter $param overwrites previous argument
741
+
683
742
foo(1, param: 2);
684
743
// Error: Named parameter $param overwrites previous argument
744
+
745
+
?>
746
+
]]>
747
+
</programlisting>
748
+
</example>
749
+
750
+
<para>
751
+
As of PHP 8.1.0, it is possible to use named arguments after unpacking the arguments.
752
+
A named argument <emphasis>must not</emphasis> override an already unpacked argument.
753
+
</para>
754
+
755
+
<example>
756
+
<title>Use named arguments after unpacking</title>
757
+
<programlisting role="php">
758
+
<![CDATA[
759
+
<?php
760
+
function foo($a, $b, $c = 3, $d = 4) {
761
+
return $a + $b + $c + $d;
762
+
}
763
+
764
+
var_dump(foo(...[1, 2], d: 40)); // 46
765
+
var_dump(foo(...['b' => 2, 'a' => 1], d: 40)); // 46
766
+
767
+
var_dump(foo(...[1, 2], b: 20)); // Fatal error. Named parameter $b overwrites previous argument
685
768
?>
686
769
]]>
687
770
</programlisting>
...
...
@@ -739,9 +822,14 @@ echo square(4); // outputs '16'.
739
822
<?php
740
823
function small_numbers()
741
824
{
742
-
return array (0, 1, 2);
825
+
return [0, 1, 2];
743
826
}
744
-
list ($zero, $one, $two) = small_numbers();
827
+
// Array destructuring will collect each member of the array individually
828
+
[$zero, $one, $two] = small_numbers();
829
+
830
+
// Prior to 7.1.0, the only equivalent alternative is using list() construct
831
+
list($zero, $one, $two) = small_numbers();
832
+
745
833
?>
746
834
]]>
747
835
</programlisting>
...
...
@@ -969,8 +1057,42 @@ $func(); // prints "bar"
969
1057
the return value of the function is undefined. In this case it will
970
1058
likely return &null; but this is just a convention, and cannot be relied
971
1059
upon.
1060
+
As of PHP 8.0.0, a <classname>TypeError</classname> exception is supposed to
1061
+
be thrown in this case.
972
1062
</simpara>
973
1063
</note>
1064
+
<note>
1065
+
<para>
1066
+
Scalar types for built-in functions are nullable by default in coercive mode.
1067
+
As of PHP 8.1.0, passing &null; to an internal function parameter that is not declared nullable
1068
+
is discouraged and emits a deprecation notice in coercive mode to align with the behavior of user-defined functions,
1069
+
where scalar types need to be marked as nullable explicitly.
1070
+
</para>
1071
+
1072
+
<para>
1073
+
For example, <function>strlen</function> function expects the parameter <literal>$string</literal>
1074
+
to be a non-nullable &string;.
1075
+
For historical reasons, PHP allows passing &null; for this parameter in coercive mode, and the parameter is
1076
+
implicitly cast to <type>string</type>, resulting in a <literal>""</literal> value.
1077
+
In contrast, a <classname>TypeError</classname> is emitted in strict mode.
1078
+
</para>
1079
+
1080
+
<informalexample>
1081
+
<programlisting role="php">
1082
+
<![CDATA[
1083
+
<?php
1084
+
var_dump(strlen(null));
1085
+
// "Deprecated: Passing null to parameter #1 ($string) of type string is deprecated" as of PHP 8.1.0
1086
+
// int(0)
1087
+
1088
+
var_dump(str_contains("foobar", null));
1089
+
// "Deprecated: Passing null to parameter #2 ($needle) of type string is deprecated" as of PHP 8.1.0
1090
+
// bool(true)
1091
+
?>
1092
+
]]>
1093
+
</programlisting>
1094
+
</informalexample>
1095
+
</note>
974
1096
975
1097
<sect2 role="seealso">
976
1098
&reftitle.seealso;
...
...
@@ -1026,8 +1148,7 @@ echo preg_replace_callback('~-([a-z])~', function ($match) {
1026
1148
<programlisting role="php">
1027
1149
<![CDATA[
1028
1150
<?php
1029
-
$greet = function($name)
1030
-
{
1151
+
$greet = function($name) {
1031
1152
printf("Hello %s\r\n", $name);
1032
1153
};
1033
1154
...
...
@@ -1043,6 +1164,8 @@ $greet('PHP');
1043
1164
variables must be passed to the <literal>use</literal> language construct.
1044
1165
As of PHP 7.1, these variables must not include &link.superglobals;,
1045
1166
<varname>$this</varname>, or variables with the same name as a parameter.
1167
+
A return type declaration of the function has to be placed
1168
+
<emphasis>after</emphasis> the <literal>use</literal> clause.
1046
1169
</simpara>
1047
1170
1048
1171
<example>
...
...
@@ -1088,6 +1211,12 @@ $example = function ($arg) use ($message) {
1088
1211
var_dump($arg . ' ' . $message);
1089
1212
};
1090
1213
$example("hello");
1214
+
1215
+
// Return type declaration comes after the use clause
1216
+
$example = function () use ($message): string {
1217
+
return "hello $message";
1218
+
};
1219
+
var_dump($example());
1091
1220
?>
1092
1221
]]>
1093
1222
</programlisting>
...
...
@@ -1101,6 +1230,7 @@ string(5) "hello"
1101
1230
string(5) "hello"
1102
1231
string(5) "world"
1103
1232
string(11) "hello world"
1233
+
string(11) "hello world"
1104
1234
]]>
1105
1235
</screen>
1106
1236
</example>
...
...
@@ -1268,7 +1398,7 @@ NULL
1268
1398
$func = static function() {
1269
1399
// function body
1270
1400
};
1271
-
$func = $func->bindTo(new StdClass);
1401
+
$func = $func->bindTo(new stdClass);
1272
1402
$func();
1273
1403
1274
1404
?>
...
...
@@ -1296,6 +1426,13 @@ Warning: Cannot bind an instance to a static closure in %s on line %d
1296
1426
</row>
1297
1427
</thead>
1298
1428
<tbody>
1429
+
<row>
1430
+
<entry>8.3.0</entry>
1431
+
<entry>
1432
+
Closures created from <link linkend="language.oop5.magic">magic
1433
+
methods</link> can accept named parameters.
1434
+
</entry>
1435
+
</row>
1299
1436
<row>
1300
1437
<entry>7.1.0</entry>
1301
1438
<entry>
...
...
@@ -1413,7 +1550,7 @@ var_export($fn(5)(10));
1413
1550
<?php
1414
1551
1415
1552
fn(array $x) => $x;
1416
-
static fn(): int => $x;
1553
+
static fn($x): int => $x;
1417
1554
fn($x = 42) => $x;
1418
1555
fn(&$x) => $x;
1419
1556
fn&($x) => $x;
...
...
@@ -1487,6 +1624,127 @@ var_export($x); // Outputs 1
1487
1624
</sect2>
1488
1625
</sect1>
1489
1626
1627
+
<sect1 xml:id="functions.first_class_callable_syntax">
1628
+
<title>First class callable syntax</title>
1629
+
1630
+
<para>
1631
+
The first class callable syntax is introduced as of PHP 8.1.0, as a way of creating <link linkend="functions.anonymous">anonymous functions</link> from <link linkend="language.types.callable">callable</link>.
1632
+
It supersedes existing callable syntax using strings and arrays.
1633
+
The advantage of this syntax is that it is accessible to static analysis, and uses the scope at the point where the callable is acquired.
1634
+
</para>
1635
+
1636
+
<para>
1637
+
<code>CallableExpr(...)</code> syntax is used to create a <classname>Closure</classname> object from callable. <code>CallableExpr</code> accepts any expression that can be directly called in the PHP grammar:
1638
+
<example>
1639
+
<title>Simple first class callable syntax</title>
1640
+
<programlisting role="php">
1641
+
<;
1666
+
$f9 = [Foo::class, 'staticmethod'](...);
1667
+
?>
1668
+
]]>
1669
+
</programlisting>
1670
+
</example>
1671
+
</para>
1672
+
1673
+
<note>
1674
+
<para>
1675
+
The <code>...</code> is part of the syntax, and not an omission.
1676
+
</para>
1677
+
</note>
1678
+
1679
+
<para>
1680
+
<code>CallableExpr(...)</code> has the same semantics as <methodname>Closure::fromCallable</methodname>.
1681
+
That is, unlike callable using strings and arrays, <code>CallableExpr(...)</code> respects the scope at the point where it is created:
1682
+
<example>
1683
+
<title>Scope comparison of <code>CallableExpr(...)</code> and traditional callable</title>
1684
+
<programlisting role="php">
1685
+
<![CDATA[
1686
+
<?php
1687
+
1688
+
class Foo {
1689
+
public function getPrivateMethod() {
1690
+
return [$this, 'privateMethod'];
1691
+
}
1692
+
1693
+
private function privateMethod() {
1694
+
echo __METHOD__, "\n";
1695
+
}
1696
+
}
1697
+
1698
+
$foo = new Foo;
1699
+
$privateMethod = $foo->getPrivateMethod();
1700
+
$privateMethod();
1701
+
// Fatal error: Call to private method Foo::privateMethod() from global scope
1702
+
// This is because call is performed outside from Foo and visibility will be checked from this point.
1703
+
1704
+
class Foo1 {
1705
+
public function getPrivateMethod() {
1706
+
// Uses the scope where the callable is acquired.
1707
+
return $this->privateMethod(...); // identical to Closure::fromCallable([$this, 'privateMethod']);
1708
+
}
1709
+
1710
+
private function privateMethod() {
1711
+
echo __METHOD__, "\n";
1712
+
}
1713
+
}
1714
+
1715
+
$foo1 = new Foo1;
1716
+
$privateMethod = $foo1->getPrivateMethod();
1717
+
$privateMethod(); // Foo1::privateMethod
1718
+
?>
1719
+
]]>
1720
+
</programlisting>
1721
+
</example>
1722
+
1723
+
</para>
1724
+
1725
+
<note>
1726
+
<para>
1727
+
Object creation by this syntax (e.g <code>new Foo(...)</code>) is not supported, because <code>new Foo()</code> syntax is not considered a call.
1728
+
</para>
1729
+
</note>
1730
+
1731
+
<note>
1732
+
<para>
1733
+
The first-class callable syntax cannot be combined with the <link linkend="language.oop5.basic.nullsafe">nullsafe operator</link>. Both of the following result in a compile-time error:
1734
+
<informalexample>
1735
+
<programlisting role="php">
1736
+
<![CDATA[
1737
+
<?php
1738
+
$obj?->method(...);
1739
+
$obj?->prop->method(...);
1740
+
?>
1741
+
]]>
1742
+
</programlisting>
1743
+
</informalexample>
1744
+
</para>
1745
+
</note>
1746
+
</sect1>
1747
+
1490
1748
</chapter>
1491
1749
1492
1750
<!-- Keep this comment at the end of the file
1493
1751