language/types/array.xml
c97d8be813dd0189f2a97359795fbe7173792878
...
...
@@ -48,10 +48,12 @@ array(
48
48
is commonly used, as it allows easier addition of new elements at the end.
49
49
</para>
50
50

51
-
<para>
52
-
As of PHP 5.4 you can also use the short array syntax, which replaces
53
-
<literal>array()</literal> with <literal>[]</literal>.
54
-
</para>
51
+
<note>
52
+
<para>
53
+
A short array syntax exists which replaces
54
+
<literal>array()</literal> with <literal>[]</literal>.
55
+
</para>
56
+
</note>
55
57

56
58
<example>
57
59
<title>A simple array</title>
...
...
@@ -63,7 +65,7 @@ $array = array(
63
65
"bar" => "foo",
64
66
);
65
67

66
-
// as of PHP 5.4
68
+
// Using the short array syntax
67
69
$array = [
68
70
"foo" => "bar",
69
71
"bar" => "foo",
...
...
@@ -74,7 +76,7 @@ $array = [
74
76
</example>
75
77
76
78
<para>
77
-
The <replaceable>key</replaceable> can either be an <type>integer</type>
79
+
The <replaceable>key</replaceable> can either be an <type>int</type>
78
80
or a <type>string</type>. The <replaceable>value</replaceable> can be
79
81
of any type.
80
82
</para>
...
...
@@ -84,24 +86,24 @@ $array = [
84
86
<itemizedlist>
85
87
<listitem>
86
88
<simpara>
87
-
<type>String</type>s containing valid decimal <type>integer</type>s, unless the number is preceded by a <literal>+</literal> sign, will be cast to the
88
-
<type>integer</type> type. E.g. the key <literal>"8"</literal> will actually be
89
+
<type>String</type>s containing valid decimal <type>int</type>s, unless the number is preceded by a <literal>+</literal> sign, will be cast to the
90
+
<type>int</type> type. E.g. the key <literal>"8"</literal> will actually be
89
91
stored under <literal>8</literal>. On the other hand <literal>"08"</literal> will
90
92
not be cast, as it isn't a valid decimal integer.
91
93
</simpara>
92
94
</listitem>
93
95
<listitem>
94
96
<simpara>
95
-
<type>Float</type>s are also cast to <type>integer</type>s, which means that the
97
+
<type>Float</type>s are also cast to <type>int</type>s, which means that the
96
98
fractional part will be truncated. E.g. the key <literal>8.7</literal> will actually
97
99
be stored under <literal>8</literal>.
98
100
</simpara>
99
101
</listitem>
100
102
<listitem>
101
103
<simpara>
102
-
<type>Bool</type>s are cast to <type>integer</type>s, too, i.e. the key
103
-
<literal>true</literal> will actually be stored under <literal>1</literal>
104
-
and the key <literal>false</literal> under <literal>0</literal>.
104
+
<type>Bool</type>s are cast to <type>int</type>s, too, i.e. the key
105
+
&true; will actually be stored under <literal>1</literal>
106
+
and the key &false; under <literal>0</literal>.
105
107
</simpara>
106
108
</listitem>
107
109
<listitem>
...
...
@@ -155,12 +157,12 @@ array(1) {
155
157
</example>
156
158
157
159
<para>
158
-
PHP arrays can contain <type>integer</type> and <type>string</type> keys at the same time
160
+
PHP arrays can contain <type>int</type> and <type>string</type> keys at the same time
159
161
as PHP does not distinguish between indexed and associative arrays.
160
162
</para>
161
163
162
164
<example>
163
-
<title>Mixed <type>integer</type> and <type>string</type> keys</title>
165
+
<title>Mixed <type>int</type> and <type>string</type> keys</title>
164
166
<programlisting role="php">
165
167
<![CDATA[
166
168
<?php
...
...
@@ -193,7 +195,7 @@ array(4) {
193
195
194
196
<para>
195
197
The <replaceable>key</replaceable> is optional. If it is not specified, PHP will
196
-
use the increment of the largest previously used <type>integer</type> key.
198
+
use the increment of the largest previously used <type>int</type> key.
197
199
</para>
198
200
199
201
<example>
...
...
@@ -263,6 +265,57 @@ array(4) {
263
265
was <literal>6</literal>.
264
266
</para>
265
267
</example>
268
+

269
+
<example>
270
+
<title>Complex Type Casting and Overwriting example</title>
271
+
<para>
272
+
This example includes all variations of type casting of keys and overwriting
273
+
of elements.
274
+
</para>
275
+
<programlisting role="php">
276
+
<![CDATA[
277
+
<?php
278
+
$array = array(
279
+
1 => 'a',
280
+
'1' => 'b', // the value "a" will be overwritten by "b"
281
+
1.5 => 'c', // the value "b" will be overwritten by "c"
282
+
-1 => 'd',
283
+
'01' => 'e', // as this is not an integer string it will NOT override the key for 1
284
+
'1.5' => 'f', // as this is not an integer string it will NOT override the key for 1
285
+
true => 'g', // the value "c" will be overwritten by "g"
286
+
false => 'h',
287
+
'' => 'i',
288
+
null => 'j', // the value "i" will be overwritten by "j"
289
+
'k', // value "k" is assigned the key 2. This is because the largest integer key before that was 1
290
+
2 => 'l', // the value "k" will be overwritten by "l"
291
+
);
292
+

293
+
var_dump($array);
294
+
?>
295
+
]]>
296
+
</programlisting>
297
+
&example.outputs;
298
+
<screen>
299
+
<![CDATA[
300
+
array(7) {
301
+
[1]=>
302
+
string(1) "g"
303
+
[-1]=>
304
+
string(1) "d"
305
+
["01"]=>
306
+
string(1) "e"
307
+
["1.5"]=>
308
+
string(1) "f"
309
+
[0]=>
310
+
string(1) "h"
311
+
[""]=>
312
+
string(1) "j"
313
+
[2]=>
314
+
string(1) "l"
315
+
}
316
+
]]>
317
+
</screen>
318
+
</example>
266
319
</sect3>
267
320
268
321
<sect3 xml:id="language.types.array.syntax.accessing">
...
...
@@ -305,22 +358,13 @@ string(3) "foo"
305
358
306
359
<note>
307
360
<para>
308
-
Both square brackets and curly braces can be used interchangeably
309
-
for accessing array elements (e.g. <literal>$array[42]</literal> and <literal>$array{42}</literal> will
310
-
both do the same thing in the example above).
361
+
Prior to PHP 8.0.0, square brackets and curly braces could be used interchangeably
362
+
for accessing array elements (e.g. <literal>$array[42]</literal> and <literal>$array{42}</literal>
363
+
would both do the same thing in the example above).
364
+
The curly brace syntax was deprecated as of PHP 7.4.0 and no longer supported as of PHP 8.0.0.
311
365
</para>
312
366
</note>
313
367

314
-
<para>
315
-
As of PHP 5.4 it is possible to array dereference the result of a function
316
-
or method call directly. Before it was only possible using a temporary
317
-
variable.
318
-
</para>
319
-
320
-
<para>
321
-
As of PHP 5.5 it is possible to array dereference an array literal.
322
-
</para>
323
-
324
368
<example>
325
369
<title>Array dereferencing</title>
326
370
<programlisting role="php">
...
...
@@ -330,15 +374,7 @@ function getArray() {
330
374
return array(1, 2, 3);
331
375
}
332
376

333
-
// on PHP 5.4
334
377
$secondElement = getArray()[1];
335
-

336
-
// previously
337
-
$tmp = getArray();
338
-
$secondElement = $tmp[1];
339
-

340
-
// or
341
-
list(, $secondElement) = getArray();
342
378
?>
343
379
]]>
344
380
</programlisting>
...
...
@@ -348,14 +384,17 @@ list(, $secondElement) = getArray();
348
384
<para>
349
385
Attempting to access an array key which has not been defined is
350
386
the same as accessing any other undefined variable:
351
-
an <constant>E_NOTICE</constant>-level error message will be
387
+
an <constant>E_WARNING</constant>-level error message
388
+
(<constant>E_NOTICE</constant>-level prior to PHP 8.0.0) will be
352
389
issued, and the result will be &null;.
353
390
</para>
354
391
</note>
355
392
<note>
356
393
<para>
357
394
Array dereferencing a scalar value which is not a <type>string</type>
358
-
silently yields &null;, i.e. without issuing an error message.
395
+
yields &null;. Prior to PHP 7.4.0, that did not issue an error message.
396
+
As of PHP 7.4.0, this issues <constant>E_NOTICE</constant>;
397
+
as of PHP 8.0.0, this issues <constant>E_WARNING</constant>.
359
398
</para>
360
399
</note>
361
400
</sect3>
...
...
@@ -377,11 +416,11 @@ list(, $secondElement) = getArray();
377
416
<synopsis>
378
417
$arr[<replaceable>key</replaceable>] = <replaceable>value</replaceable>;
379
418
$arr[] = <replaceable>value</replaceable>;
380
-
// <replaceable>key</replaceable> may be an <type>integer</type> or <type>string</type>
419
+
// <replaceable>key</replaceable> may be an <type>int</type> or <type>string</type>
381
420
// <replaceable>value</replaceable> may be any value of any type</synopsis>
382
421
383
422
<para>
384
-
If <varname>$arr</varname> doesn't exist yet, it will be created, so this is
423
+
If <varname>$arr</varname> doesn't exist yet or is set to &null; or &false;, it will be created, so this is
385
424
also an alternative way to create an <type>array</type>. This practice is
386
425
however discouraged because if <varname>$arr</varname> already contains
387
426
some value (e.g. <type>string</type> from request variable) then this
...
...
@@ -396,6 +435,12 @@ $arr[] = <replaceable>value</replaceable>;
396
435
error. Formerly, the string was silently converted to an array.
397
436
</simpara>
398
437
</note>
438
+
<note>
439
+
<simpara>
440
+
As of PHP 8.1.0, creating a new array from &false; value is deprecated.
441
+
Creating a new array from &null; and undefined values is still allowed.
442
+
</simpara>
443
+
</note>
399
444

400
445
<para>
401
446
To change a certain
...
...
@@ -426,8 +471,8 @@ unset($arr); // This deletes the whole array
426
471
<note>
427
472
<para>
428
473
As mentioned above, if no key is specified, the maximum of the existing
429
-
<type>integer</type> indices is taken, and the new key will be that maximum
430
-
value plus 1 (but at least 0). If no <type>integer</type> indices exist yet, the key will
474
+
<type>int</type> indices is taken, and the new key will be that maximum
475
+
value plus 1 (but at least 0). If no <type>int</type> indices exist yet, the key will
431
476
be <literal>0</literal> (zero).
432
477
</para>
433
478

...
...
@@ -493,6 +538,139 @@ Array
493
538
</note>
494
539

495
540
</sect3>
541
+

542
+
<sect3 xml:id="language.types.array.syntax.destructuring">
543
+
<title>Array destructuring</title>
544
+

545
+
<para>
546
+
Arrays can be destructured using the <literal>[]</literal> (as of PHP 7.1.0) or
547
+
<function>list</function> language constructs. These
548
+
constructs can be used to destructure an array into distinct variables.
549
+
</para>
550
+

551
+
<informalexample>
552
+
<programlisting role="php">
553
+
<![CDATA[
554
+
<?php
555
+
$source_array = ['foo', 'bar', 'baz'];
556
+

557
+
[$foo, $bar, $baz] = $source_array;
558
+

559
+
echo $foo; // prints "foo"
560
+
echo $bar; // prints "bar"
561
+
echo $baz; // prints "baz"
562
+
?>
563
+
]]>
564
+
</programlisting>
565
+
</informalexample>
566
+

567
+
<para>
568
+
Array destructuring can be used in &foreach; to destructure
569
+
a multi-dimensional array while iterating over it.
570
+
</para>
571
+

572
+
<informalexample>
573
+
<programlisting role="php">
574
+
<![CDATA[
575
+
<?php
576
+
$source_array = [
577
+
[1, 'John'],
578
+
[2, 'Jane'],
579
+
];
580
+

581
+
foreach ($source_array as [$id, $name]) {
582
+
// logic here with $id and $name
583
+
}
584
+
?>
585
+
]]>
586
+
</programlisting>
587
+
</informalexample>
588
+

589
+
<para>
590
+
Array elements will be ignored if the variable is not provided. Array
591
+
destructuring always starts at index <literal>0</literal>.
592
+
</para>
593
+

594
+
<informalexample>
595
+
<programlisting role="php">
596
+
<![CDATA[
597
+
<?php
598
+
$source_array = ['foo', 'bar', 'baz'];
599
+

600
+
// Assign the element at index 2 to the variable $baz
601
+
[, , $baz] = $source_array;
602
+

603
+
echo $baz; // prints "baz"
604
+
?>
605
+
]]>
606
+
</programlisting>
607
+
</informalexample>
608
+

609
+
<para>
610
+
As of PHP 7.1.0, associative arrays can be destructured too. This also
611
+
allows for easier selection of the right element in numerically indexed
612
+
arrays as the index can be explicitly specified.
613
+
</para>
614
+

615
+
<informalexample>
616
+
<programlisting role="php">
617
+
<![CDATA[
618
+
<?php
619
+
$source_array = ['foo' => 1, 'bar' => 2, 'baz' => 3];
620
+

621
+
// Assign the element at index 'baz' to the variable $three
622
+
['baz' => $three] = $source_array;
623
+

624
+
echo $three; // prints 3
625
+

626
+
$source_array = ['foo', 'bar', 'baz'];
627
+

628
+
// Assign the element at index 2 to the variable $baz
629
+
[2 => $baz] = $source_array;
630
+

631
+
echo $baz; // prints "baz"
632
+
?>
633
+
]]>
634
+
</programlisting>
635
+
</informalexample>
636
+

637
+
<para>
638
+
Array destructuring can be used for easy swapping of two variables.
639
+
</para>
640
+

641
+
<informalexample>
642
+
<programlisting role="php">
643
+
<![CDATA[
644
+
<?php
645
+
$a = 1;
646
+
$b = 2;
647
+

648
+
[$b, $a] = [$a, $b];
649
+

650
+
echo $a; // prints 2
651
+
echo $b; // prints 1
652
+
?>
653
+
]]>
654
+
</programlisting>
655
+
</informalexample>
656
+

657
+
<note>
658
+
<para>
659
+
The spread operator (<literal>...</literal>) is not supported in assignments.
660
+
</para>
661
+
</note>
662
+

663
+
<note>
664
+
<para>
665
+
Attempting to access an array key which has not been defined is
666
+
the same as accessing any other undefined variable:
667
+
an <constant>E_WARNING</constant>-level error message
668
+
(<constant>E_NOTICE</constant>-level prior to PHP 8.0.0) will be
669
+
issued, and the result will be &null;.
670
+
</para>
671
+
</note>
672
+
</sect3>
673
+

496
674
</sect2><!-- end syntax -->
497
675
498
676
<sect2 xml:id="language.types.array.useful-funcs">
...
...
@@ -576,9 +754,12 @@ echo $foo[bar];
576
754
</para>
577
755
<warning>
578
756
<simpara>
579
-
The fallback to treat an undefined constant as bare string is deprecated as
580
-
of PHP 7.2.0, and issues an error of level <constant>E_WARNING</constant>.
581
-
Formerly, an error of level <constant>E_NOTICE</constant> has been issued.
757
+
The fallback to treat an undefined constant as bare string issues an error
758
+
of level <constant>E_NOTICE</constant>.
759
+
This has been deprecated as of PHP 7.2.0, and issues an error
760
+
of level <constant>E_WARNING</constant>.
761
+
As of PHP 8.0.0, it has been removed and throws an
762
+
<classname>Error</classname> exception.
582
763
</simpara>
583
764
</warning>
584
765

...
...
@@ -780,8 +961,8 @@ $error_descriptions[8] = "This is just an informal notice";
780
961
<title>Converting to array</title>
781
962
782
963
<para>
783
-
For any of the types <type>integer</type>, <type>float</type>,
784
-
<type>string</type>, <type>boolean</type> and <type>resource</type>,
964
+
For any of the types <type>int</type>, <type>float</type>,
965
+
<type>string</type>, <type>bool</type> and <type>resource</type>,
785
966
converting a value to an <type>array</type> results in an array with a single
786
967
element with index zero and the value of the scalar which was converted. In
787
968
other words, <literal>(array)$scalarValue</literal> is exactly the same as
...
...
@@ -795,8 +976,45 @@ $error_descriptions[8] = "This is just an informal notice";
795
976
exceptions: integer properties are unaccessible;
796
977
private variables have the class name prepended to the variable
797
978
name; protected variables have a '*' prepended to the variable name. These
798
-
prepended values have null bytes on either side. This can result in some
799
-
unexpected behaviour:
979
+
prepended values have <literal>NUL</literal> bytes on either side.
980
+
Uninitialized <link linkend="language.oop5.properties.typed-properties">typed properties</link>
981
+
are silently discarded.
982
+
</para>
983
+

984
+
<informalexample>
985
+
<programlisting role="php">
986
+
<![CDATA[
987
+
<?php
988
+

989
+
class A {
990
+
private $B;
991
+
protected $C;
992
+
public $D;
993
+
function __construct()
994
+
{
995
+
$this->{1} = null;
996
+
}
997
+
}
998
+

999
+
var_export((array) new A());
1000
+
?>
1001
+
]]>
1002
+
</programlisting>
1003
+
&example.outputs;
1004
+
<screen>
1005
+
<![CDATA[
1006
+
array (
1007
+
'' . "\0" . 'A' . "\0" . 'B' => NULL,
1008
+
'' . "\0" . '*' . "\0" . 'C' => NULL,
1009
+
'D' => NULL,
1010
+
1 => NULL,
1011
+
)
1012
+
]]>
1013
+
</screen>
1014
+
</informalexample>
1015
+

1016
+
<para>
1017
+
These <literal>NUL</literal> can result in some unexpected behaviour:
800
1018
</para>
801
1019

802
1020
<informalexample>
...
...
@@ -817,6 +1035,19 @@ var_dump((array) new B());
817
1035
?>
818
1036
]]>
819
1037
</programlisting>
1038
+
&example.outputs;
1039
+
<screen>
1040
+
<![CDATA[
1041
+
array(3) {
1042
+
["BA"]=>
1043
+
NULL
1044
+
["AA"]=>
1045
+
NULL
1046
+
["AA"]=>
1047
+
NULL
1048
+
}
1049
+
]]>
1050
+
</screen>
820
1051
</informalexample>
821
1052

822
1053
<para>
...
...
@@ -840,6 +1071,100 @@ var_dump((array) new B());
840
1071
</para>
841
1072
</sect2>
842
1073

1074
+
<sect2 xml:id="language.types.array.unpacking">
1075
+
<title>Array unpacking</title>
1076
+

1077
+
<para>
1078
+
An array prefixed by <code>...</code> will be expanded in place during array definition.
1079
+
Only arrays and objects which implement <interfacename>Traversable</interfacename> can be expanded.
1080
+
Array unpacking with <code>...</code> is available as of PHP 7.4.0.
1081
+
</para>
1082
+

1083
+
<para>
1084
+
It's possible to expand multiple times, and add normal elements before or after the <code>...</code> operator:
1085
+

1086
+
<example>
1087
+
<title>Simple array unpacking</title>
1088
+
<programlisting role="php">
1089
+
<![CDATA[
1090
+
<?php
1091
+
// Using short array syntax.
1092
+
// Also, works with array() syntax.
1093
+
$arr1 = [1, 2, 3];
1094
+
$arr2 = [...$arr1]; //[1, 2, 3]
1095
+
$arr3 = [0, ...$arr1]; //[0, 1, 2, 3]
1096
+
$arr4 = [...$arr1, ...$arr2, 111]; //[1, 2, 3, 1, 2, 3, 111]
1097
+
$arr5 = [...$arr1, ...$arr1]; //[1, 2, 3, 1, 2, 3]
1098
+

1099
+
function getArr() {
1100
+
return ['a', 'b'];
1101
+
}
1102
+
$arr6 = [...getArr(), 'c' => 'd']; //['a', 'b', 'c' => 'd']
1103
+
?>
1104
+
]]>
1105
+
</programlisting>
1106
+
</example>
1107
+
</para>
1108
+

1109
+
<para>
1110
+
Unpacking an array with the <code>...</code> operator follows the semantics of the <function>array_merge</function> function.
1111
+
That is, later string keys overwrite earlier ones and integer keys are renumbered:
1112
+

1113
+
<example>
1114
+
<title>Array unpacking with duplicate key</title>
1115
+
<programlisting role="php">
1116
+
<![CDATA[
1117
+
<?php
1118
+
// string key
1119
+
$arr1 = ["a" => 1];
1120
+
$arr2 = ["a" => 2];
1121
+
$arr3 = ["a" => 0, ...$arr1, ...$arr2];
1122
+
var_dump($arr3); // ["a" => 2]
1123
+

1124
+
// integer key
1125
+
$arr4 = [1, 2, 3];
1126
+
$arr5 = [4, 5, 6];
1127
+
$arr6 = [...$arr4, ...$arr5];
1128
+
var_dump($arr6); // [1, 2, 3, 4, 5, 6]
1129
+
// Which is [0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 => 6]
1130
+
// where the original integer keys have not been retained.
1131
+
?>
1132
+
]]>
1133
+
</programlisting>
1134
+
</example>
1135
+
</para>
1136
+

1137
+
<note>
1138
+
<para>
1139
+
Keys that are neither integers nor strings throw a <classname>TypeError</classname>.
1140
+
Such keys can only be generated by a <interfacename>Traversable</interfacename> object.
1141
+
</para>
1142
+
</note>
1143
+
<note>
1144
+
<para>
1145
+
Prior to PHP 8.1, unpacking an array which has a string key is not supported:
1146
+
</para>
1147
+
<informalexample>
1148
+
<programlisting role="php">
1149
+
<![CDATA[
1150
+
<?php
1151
+

1152
+
$arr1 = [1, 2, 3];
1153
+
$arr2 = ['a' => 4];
1154
+
$arr3 = [...$arr1, ...$arr2];
1155
+
// Fatal error: Uncaught Error: Cannot unpack array with string keys in example.php:5
1156
+

1157
+
$arr4 = [1, 2, 3];
1158
+
$arr5 = [4, 5];
1159
+
$arr6 = [...$arr4, ...$arr5]; // works. [1, 2, 3, 4, 5]
1160
+
?>
1161
+
]]>
1162
+
</programlisting>
1163
+
</informalexample>
1164
+
</note>
1165
+

1166
+
</sect2>
1167
+

843
1168
<sect2 xml:id="language.types.array.examples">
844
1169
<title>Examples</title>
845
1170

...
...
@@ -962,7 +1287,7 @@ Do you like yellow?
962
1287
<![CDATA[
963
1288
<?php
964
1289
foreach ($colors as &$color) {
965
-
$color = strtoupper($color);
1290
+
$color = mb_strtoupper($color);
966
1291
}
967
1292
unset($color); /* ensure that following writes to
968
1293
$color will not modify the last array element */
969
1294