language/functions.xml
f94d903985119d3ac00f4528551df947f57b667f
...
...
@@ -227,28 +227,6 @@ function takes_many_args(
227
227
]]>
228
228
</programlisting>
229
229
</example>
230
-
<para>
231
-
As of PHP 8.0.0, declaring mandatory arguments after optional arguments
232
-
is deprecated. This can generally be resolved by dropping the default value.
233
-
One exception to this rule are arguments of the form
234
-
<code>Type $param = null</code>, where the &null; default makes the type implicitly
235
-
nullable. This usage remains allowed, though it is recommended to use an
236
-
explicit nullable type instead.
237
-
</para>
238
-
<example>
239
-
<title>Declaring optional arguments after mandatory arguments</title>
240
-
<programlisting role="php">
241
-
<![CDATA[
242
-
<?php
243
-
function foo($a = [], $b) {} // Before
244
-
function foo($a, $b) {} // After
245
-

246
-
function bar(A $a = null, $b) {} // Still allowed
247
-
function bar(?A $a, $b) {} // Recommended
248
-
?>
249
-
]]>
250
-
</programlisting>
251
-
</example>
252
230

253
231
<sect2 xml:id="functions.arguments.by-reference">
254
232
<title>Passing arguments by reference</title>
...
...
@@ -289,8 +267,10 @@ echo $str; // outputs 'This is a string, and something extra.'
289
267
<title>Default argument values</title>
290
268
291
269
<para>
292
-
A function may define C++-style default values for scalar
293
-
arguments as follows:
270
+
A function may define default values for arguments using syntax similar
271
+
to assigning a variable. The default is used only when the parameter is
272
+
not specified; in particular, note that passing &null; does <emphasis>not</emphasis>
273
+
assign the default value.
294
274
</para>
295
275
<para>
296
276
<example>
...
...
@@ -319,8 +299,9 @@ Making a cup of espresso.
319
299
</example>
320
300
</para>
321
301
<para>
322
-
PHP also allows the use of <type>array</type>s and the special type &null;
323
-
as default values, for example:
302
+
Default parameter values may be scalar values, <type>array</type>s,
303
+
the special type &null;, and as of PHP 8.1.0, objects using the
304
+
<link linkend="language.oop5.basic.new">new ClassName()</link> syntax.
324
305
</para>
325
306
<para>
326
307
<example>
...
...
@@ -334,21 +315,61 @@ function makecoffee($types = array("cappuccino"), $coffeeMaker = NULL)
334
315
return "Making a cup of ".join(", ", $types)." with $device.\n";
335
316
}
336
317
echo makecoffee();
337
-
echo makecoffee(array("cappuccino", "lavazza"), "teapot");
338
-
?>
318
+
echo makecoffee(array("cappuccino", "lavazza"), "teapot");?>
339
319
]]>
340
320
</programlisting>
321
+
&example.outputs;
322
+
<screen>
323
+
<![CDATA[
324
+
Making a cup of cappuccino with hands.
325
+
Making a cup of cappuccino, lavazza with teapot.
326
+
]]>
327
+
</screen>
341
328
</example>
329
+
</para>
330
+
<para>
331
+
<example>
332
+
<title>Using objects as default values (as of PHP 8.1.0)</title>
333
+
<programlisting role="php">
334
+
<![CDATA[
335
+
<?php
336
+
class DefaultCoffeeMaker {
337
+
public function brew() {
338
+
return "Making coffee.\n";
339
+
}
340
+
}
341
+
class FancyCoffeeMaker {
342
+
public function brew() {
343
+
return "Crafting a beautiful coffee just for you.\n";
344
+
}
345
+
}
346
+
function makecoffee($coffeeMaker = new DefaultCoffeeMaker)
347
+
{
348
+
return $coffeeMaker->brew();
349
+
}
350
+
echo makecoffee();
351
+
echo makecoffee(new FancyCoffeeMaker);
352
+
?>
353
+
]]>
354
+
</programlisting>
342
355

356
+
&example.outputs;
357
+
<screen>
358
+
<![CDATA[
359
+
Making coffee.
360
+
Crafting a beautiful coffee just for you.
361
+
]]>
362
+
</screen>
363
+
</example>
343
364
</para>
344
365
<simpara>
345
366
The default value must be a constant expression, not (for
346
367
example) a variable, a class member or a function call.
347
368
</simpara>
348
369
<para>
349
-
Note that when using default arguments, any defaults should be on
350
-
the right side of any non-default arguments; otherwise, things
351
-
will not work as expected. Consider the following code snippet:
370
+
Note that any optional arguments should be specified after any
371
+
required arguments, otherwise they cannot be omitted from calls.
372
+
Consider the following example:
352
373
</para>
353
374
<para>
354
375
<example>
...
...
@@ -356,21 +377,20 @@ echo makecoffee(array("cappuccino", "lavazza"), "teapot");
356
377
<programlisting role="php">
357
378
<![CDATA[
358
379
<?php
359
-
function makeyogurt($type = "acidophilus", $flavour)
380
+
function makeyogurt($container = "bowl", $flavour)
360
381
{
361
-
return "Making a bowl of $type $flavour.\n";
382
+
return "Making a $container of $flavour yogurt.\n";
362
383
}
363
384
364
-
echo makeyogurt("raspberry"); // won't work as expected
385
+
echo makeyogurt("raspberry"); // "raspberry" is $container, not $flavour
365
386
?>
366
387
]]>
367
388
</programlisting>
368
389
&example.outputs;
369
390
<screen>
370
391
<![CDATA[
371
-
Warning: Missing argument 2 in call to makeyogurt() in
372
-
/usr/local/etc/httpd/htdocs/phptest/functest.html on line 41
373
-
Making a bowl of raspberry .
392
+
Fatal error: Uncaught ArgumentCountError: Too few arguments
393
+
to function makeyogurt(), 1 passed in example.php on line 42
374
394
]]>
375
395
</screen>
376
396
</example>
...
...
@@ -384,23 +404,80 @@ Making a bowl of raspberry .
384
404
<programlisting role="php">
385
405
<![CDATA[
386
406
<?php
387
-
function makeyogurt($flavour, $type = "acidophilus")
407
+
function makeyogurt($flavour, $container = "bowl")
388
408
{
389
-
return "Making a bowl of $type $flavour.\n";
409
+
return "Making a $container of $flavour yogurt.\n";
390
410
}
391
411
392
-
echo makeyogurt("raspberry"); // works as expected
412
+
echo makeyogurt("raspberry"); // "raspberry" is $flavour
393
413
?>
394
414
]]>
395
415
</programlisting>
396
416
&example.outputs;
397
417
<screen>
398
418
<![CDATA[
399
-
Making a bowl of acidophilus raspberry.
419
+
Making a bowl of raspberry yogurt.
400
420
]]>
401
421
</screen>
402
422
</example>
403
423
</para>
424
+
<para>
425
+
As of PHP 8.0.0, <link linkend="functions.named-arguments">named arguments</link>
426
+
can be used to skip over multiple optional parameters.
427
+
</para>
428
+
<para>
429
+
<example>
430
+
<title>Correct usage of default function arguments</title>
431
+
<programlisting role="php">
432
+
<![CDATA[
433
+
<?php
434
+
function makeyogurt($container = "bowl", $flavour = "raspberry", $style = "Greek")
435
+
{
436
+
return "Making a $container of $flavour $style yogurt.\n";
437
+
}
438
+

439
+
echo makeyogurt(style: "natural");
440
+
?>
441
+
]]>
442
+
</programlisting>
443
+
&example.outputs;
444
+
<screen>
445
+
<![CDATA[
446
+
Making a bowl of raspberry natural yogurt.
447
+
]]>
448
+
</screen>
449
+
</example>
450
+
</para>
451
+
<para>
452
+
As of PHP 8.0.0, declaring mandatory arguments after optional arguments
453
+
is <emphasis>deprecated</emphasis>. This can generally be resolved by
454
+
dropping the default value, since it will never be used.
455
+
One exception to this rule are arguments of the form
456
+
<code>Type $param = null</code>, where the &null; default makes the type implicitly
457
+
nullable. This usage remains allowed, though it is recommended to use an
458
+
explicit <link linkend="language.types.declarations.nullable">nullable type</link> instead.
459
+
<example>
460
+
<title>Declaring optional arguments after mandatory arguments</title>
461
+
<programlisting role="php">
462
+
<![CDATA[
463
+
<?php
464
+
function foo($a = [], $b) {} // Default not used; deprecated as of PHP 8.0.0
465
+
function foo($a, $b) {} // Functionally equivalent, no deprecation notice
466
+

467
+
function bar(A $a = null, $b) {} // Still allowed; $a is required but nullable
468
+
function bar(?A $a, $b) {} // Recommended
469
+
?>
470
+
]]>
471
+
</programlisting>
472
+
</example>
473
+
</para>
474
+
<note>
475
+
<simpara>
476
+
As of PHP 7.1.0, omitting a parameter which does not specify a default
477
+
throws an <classname>ArgumentCountError</classname>; in previous versions
478
+
it raised a Warning.
479
+
</simpara>
480
+
</note>
404
481
<note>
405
482
<simpara>
406
483
Arguments that are passed by reference may have a default value.
...
...
@@ -417,22 +494,11 @@ Making a bowl of acidophilus raspberry.
417
494
<literal>...</literal> token.
418
495
</simpara>
419
496

420
-
<note>
421
-
<simpara>
422
-
It is also possible to achieve variable-length arguments by using
423
-
<function>func_num_args</function>,
424
-
<function>func_get_arg</function>, and
425
-
<function>func_get_args</function> functions.
426
-
This technique is not recommended as it was used prior to the introduction
427
-
of the <literal>...</literal> token.
428
-
</simpara>
429
-
</note>
430
-

431
497
<para>
432
498
Argument lists may include the
433
499
<literal>...</literal> token to denote that the function accepts a
434
500
variable number of arguments. The arguments will be passed into the
435
-
given variable as an array; for example:
501
+
given variable as an &array;:
436
502

437
503
<example>
438
504
<title>Using <literal>...</literal> to access variable arguments</title>
...
...
@@ -543,46 +609,6 @@ Catchable fatal error: Argument 2 passed to total_intervals() must be an instanc
543
609
(<literal>&amp;</literal>).
544
610
</para>
545
611

546
-
<sect3 xml:id="functions.variable-arg-list.old">
547
-
<title>Older versions of PHP</title>
548
-

549
-
<para>
550
-
No special syntax is required to note that a function is variadic;
551
-
however access to the function's arguments must use
552
-
<function>func_num_args</function>, <function>func_get_arg</function>
553
-
and <function>func_get_args</function>.
554
-
</para>
555
-

556
-
<para>
557
-
The first example above would be implemented as follows in old versions of PHP:
558
-

559
-
<example>
560
-
<title>Accessing variable arguments in old PHP versions</title>
561
-
<programlisting role="php">
562
-
<![CDATA[
563
-
<?php
564
-
function sum() {
565
-
$acc = 0;
566
-
foreach (func_get_args() as $n) {
567
-
$acc += $n;
568
-
}
569
-
return $acc;
570
-
}
571
-

572
-
echo sum(1, 2, 3, 4);
573
-
?>
574
-
]]>
575
-
</programlisting>
576
-
&example.outputs;
577
-
<screen>
578
-
<![CDATA[
579
-
10
580
-
]]>
581
-
</screen>
582
-
</example>
583
-
</para>
584
-
</sect3>
585
-

586
612
</sect2>
587
613

588
614
<sect2 xml:id="functions.named-arguments">
...
...
@@ -606,7 +632,7 @@ echo sum(1, 2, 3, 4);
606
632
<example>
607
633
<title>Named argument syntax</title>
608
634
<programlisting role="php">
609
-
<![CDATA[
635
+
<![CDATA[
610
636
<?php
611
637
myFunction(paramName: $value);
612
638
array_foobar(array: $value);
...
...
@@ -621,7 +647,7 @@ function_name($variableStoringParamName: $value);
621
647
<example>
622
648
<title>Positional arguments versus named arguments</title>
623
649
<programlisting role="php">
624
-
<![CDATA[
650
+
<![CDATA[
625
651
<?php
626
652
// Using positional arguments:
627
653
array_fill(0, 100, 50);
...
...
@@ -640,7 +666,7 @@ array_fill(start_index: 0, count: 100, value: 50);
640
666
<example>
641
667
<title>Same example as above with a different order of parameters</title>
642
668
<programlisting role="php">
643
-
<![CDATA[
669
+
<![CDATA[
644
670
<?php
645
671
array_fill(value: 50, count: 100, start_index: 0);
646
672
?>
...
...
@@ -658,7 +684,7 @@ array_fill(value: 50, count: 100, start_index: 0);
658
684
<example>
659
685
<title>Combining named arguments with positional arguments</title>
660
686
<programlisting role="php">
661
-
<![CDATA[
687
+
<![CDATA[
662
688
<?php
663
689
htmlspecialchars($string, double_encode: false);
664
690
// Same as
...
...
@@ -673,9 +699,9 @@ htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, 'UTF-8', fa
673
699
</para>
674
700

675
701
<example>
676
-
<title>Error exception when passing the same parameter multiple times</title>
702
+
<title>Error thrown when passing the same parameter multiple times</title>
677
703
<programlisting role="php">
678
-
<![CDATA[
704
+
<![CDATA[
679
705
<?php
680
706
function foo($param) { ... }
681
707

...
...
@@ -688,6 +714,29 @@ foo(1, param: 2);
688
714
</programlisting>
689
715
</example>
690
716

717
+
<para>
718
+
As of PHP 8.1.0, it is possible to use named arguments after unpacking the arguments.
719
+
A named argument <emphasis>must not</emphasis> override an already unpacked argument.
720
+
</para>
721
+

722
+
<example>
723
+
<title>Use named arguments after unpacking</title>
724
+
<programlisting role="php">
725
+
<![CDATA[
726
+
<?php
727
+
function foo($a, $b, $c = 3, $d = 4) {
728
+
return $a + $b + $c + $d;
729
+
}
730
+

731
+
var_dump(foo(...[1, 2], d: 40)); // 46
732
+
var_dump(foo(...['b' => 2, 'a' => 1], d: 40)); // 46
733
+

734
+
var_dump(foo(...[1, 2], b: 20)); // Fatal error. Named parameter $b overwrites previous argument
735
+
?>
736
+
]]>
737
+
</programlisting>
738
+
</example>
739
+

691
740
</sect2>
692
741
</sect1>
693
742
...
...
@@ -979,6 +1028,38 @@ $func(); // prints "bar"
979
1028
be thrown in this case.
980
1029
</simpara>
981
1030
</note>
1031
+
<note>
1032
+
<para>
1033
+
Scalar types for built-in functions are nullable by default in coercive mode.
1034
+
As of PHP 8.1.0, passing &null; to an internal function parameter that is not declared nullable
1035
+
is discouraged and emits a deprecation notice in coercive mode to align with the behavior of user-defined functions,
1036
+
where scalar types need to be marked as nullable explicitly.
1037
+
</para>
1038
+

1039
+
<para>
1040
+
For example, <function>strlen</function> function expects the parameter <literal>$string</literal>
1041
+
to be a non-nullable &string;.
1042
+
For historical reasons, PHP allows passing &null; for this parameter in coercive mode, and the parameter is
1043
+
implicitly cast to <type>string</type>, resulting in a <literal>""</literal> value.
1044
+
In contrast, a <classname>TypeError</classname> is emitted in strict mode.
1045
+
</para>
1046
+

1047
+
<informalexample>
1048
+
<programlisting role="php">
1049
+
<![CDATA[
1050
+
<?php
1051
+
var_dump(strlen(null));
1052
+
// "Deprecated: Passing null to parameter #1 ($string) of type string is deprecated" as of PHP 8.1.0
1053
+
// int(0)
1054
+

1055
+
var_dump(str_contains("foobar", null));
1056
+
// "Deprecated: Passing null to parameter #2 ($needle) of type string is deprecated" as of PHP 8.1.0
1057
+
// bool(true)
1058
+
?>
1059
+
]]>
1060
+
</programlisting>
1061
+
</informalexample>
1062
+
</note>
982
1063

983
1064
<sect2 role="seealso">
984
1065
&reftitle.seealso;
...
...
@@ -1034,8 +1115,7 @@ echo preg_replace_callback('~-([a-z])~', function ($match) {
1034
1115
<programlisting role="php">
1035
1116
<![CDATA[
1036
1117
<?php
1037
-
$greet = function($name)
1038
-
{
1118
+
$greet = function($name) {
1039
1119
printf("Hello %s\r\n", $name);
1040
1120
};
1041
1121

...
...
@@ -1285,7 +1365,7 @@ NULL
1285
1365
$func = static function() {
1286
1366
// function body
1287
1367
};
1288
-
$func = $func->bindTo(new StdClass);
1368
+
$func = $func->bindTo(new stdClass);
1289
1369
$func();
1290
1370

1291
1371
?>
...
...
@@ -1611,7 +1691,7 @@ $privateMethod(); // Foo1::privateMethod
1611
1691
<note>
1612
1692
<para>
1613
1693
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:
1614
-
<example>
1694
+
<informalexample>
1615
1695
<programlisting role="php">
1616
1696
<![CDATA[
1617
1697
<?php
...
...
@@ -1620,7 +1700,7 @@ $obj?->prop->method(...);
1620
1700
?>
1621
1701
]]>
1622
1702
</programlisting>
1623
-
</example>
1703
+
</informalexample>
1624
1704
</para>
1625
1705
</note>
1626
1706
</sect1>
1627
1707