language/operators.xml
52407313885d27a4e891e08dd2e2481bcc39e244
...
...
@@ -1,2808 +1,49 @@
1
1
<?xml version="1.0" encoding="utf-8"?>
2
2
<!-- $Revision$ -->
3
-
<chapter xml:id="language.operators" xmlns="http://docbook.org/ns/docbook">
4
-
<title>Operators</title>
5
-
<simpara>
6
-
An operator is something that takes one or more values (or
7
-
expressions, in programming jargon) and yields another value (so that the
8
-
construction itself becomes an expression).
9
-
</simpara>
10
-
<para>
11
-
Operators can be grouped according to the number of values they take. Unary
12
-
operators take only one value, for example <literal>!</literal> (the
13
-
<link linkend="language.operators.logical">logical not operator</link>) or
14
-
<literal>++</literal> (the
15
-
<link linkend="language.operators.increment">increment operator</link>).
16
-
Binary operators take two values, such as the familiar
17
-
<link linkend="language.operators.arithmetic">arithmetical operators</link>
18
-
<literal>+</literal> (plus) and <literal>-</literal> (minus), and the
19
-
majority of PHP operators fall into this category. Finally, there is a
20
-
single <link linkend="language.operators.comparison.ternary">ternary
21
-
operator</link>, <literal>? :</literal>, which takes three values; this is
22
-
usually referred to simply as "the ternary operator" (although it could
23
-
perhaps more properly be called the conditional operator).
24
-
</para>
25
-
<para>
26
-
A full list of PHP operators follows in the section
27
-
<link linkend="language.operators.precedence">Operator Precedence</link>.
28
-
The section also explains operator precedence and associativity, which govern
29
-
exactly how expressions containing several different operators are
30
-
evaluated.
31
-
</para>
32
-

33
-
<sect1 xml:id="language.operators.precedence">
34
-
<title>Operator Precedence</title>
35
-
<para>
36
-
The precedence of an operator specifies how "tightly" it binds two
37
-
expressions together. For example, in the expression <literal>1 +
38
-
5 * 3</literal>, the answer is <literal>16</literal> and not
39
-
<literal>18</literal> because the multiplication ("*") operator
40
-
has a higher precedence than the addition ("+") operator.
41
-
Parentheses may be used to force precedence, if necessary. For
42
-
instance: <literal>(1 + 5) * 3</literal> evaluates to
43
-
<literal>18</literal>.
44
-
</para>
45
-
<para>
46
-
When operators have equal precedence their associativity decides
47
-
how the operators are grouped. For example "-" is left-associative, so
48
-
<literal>1 - 2 - 3</literal> is grouped as <literal>(1 - 2) - 3</literal>
49
-
and evaluates to <literal>-4</literal>. "=" on the other hand is
50
-
right-associative, so <literal>$a = $b = $c</literal> is grouped as
51
-
<literal>$a = ($b = $c)</literal>.
52
-
</para>
53
-
<para>
54
-
Operators of equal precedence that are non-associative cannot be used
55
-
next to each other, for example <literal>1 &lt; 2 &gt; 1</literal> is
56
-
illegal in PHP. The expression <literal>1 &lt;= 1 == 1</literal> on the
57
-
other hand is legal, because the <literal>==</literal> operator has a lower
58
-
precedence than the <literal>&lt;=</literal> operator.
59
-
</para>
60
-
<para>
61
-
Associativity is only meaningful for binary (and ternary) operators.
62
-
Unary operators are either prefix or postfix so this notion is not applicable.
63
-
For example <literal>!!$a</literal> can only be grouped as <literal>!(!$a)</literal>.
64
-
</para>
65
-
<para>
66
-
Use of parentheses, even when not strictly necessary, can often increase
67
-
readability of the code by making grouping explicit rather than relying
68
-
on the implicit operator precedence and associativity.
69
-
</para>
70
-
<para>
71
-
The following table lists the operators in order of precedence, with
72
-
the highest-precedence ones at the top. Operators on the same line
73
-
have equal precedence, in which case associativity decides grouping.
74
-
<table>
75
-
<title>Operator Precedence</title>
76
-
<tgroup cols="2">
77
-
<thead>
78
-
<row>
79
-
<entry>Associativity</entry>
80
-
<entry>Operators</entry>
81
-
<entry>Additional Information</entry>
82
-
</row>
83
-
</thead>
84
-
<tbody>
85
-
<row>
86
-
<entry>(n/a)</entry>
87
-
<entry>
88
-
<literal>clone</literal>
89
-
<literal>new</literal>
90
-
</entry>
91
-
<entry><link linkend="language.oop5.cloning">clone</link> and <link linkend="language.oop5.basic.new">new</link></entry>
92
-
</row>
93
-
<row>
94
-
<entry>right</entry>
95
-
<entry><literal>**</literal></entry>
96
-
<entry><link linkend="language.operators.arithmetic">arithmetic</link></entry>
97
-
</row>
98
-
<row>
99
-
<entry>(n/a)</entry>
100
-
<entry>
101
-
<literal>+</literal>
102
-
<literal>-</literal>
103
-
<literal>++</literal>
104
-
<literal>--</literal>
105
-
<literal>~</literal>
106
-
<literal>(int)</literal>
107
-
<literal>(float)</literal>
108
-
<literal>(string)</literal>
109
-
<literal>(array)</literal>
110
-
<literal>(object)</literal>
111
-
<literal>(bool)</literal>
112
-
<literal>@</literal>
113
-
</entry>
114
-
<entry>
115
-
<link linkend="language.operators.arithmetic">arithmetic</link> (unary <literal>+</literal> and <literal>-</literal>),
116
-
<link linkend="language.operators.increment">increment/decrement</link>,
117
-
<link linkend="language.operators.bitwise">bitwise</link>,
118
-
<link linkend="language.types.typecasting">type casting</link>&listendand;
119
-
<link linkend="language.operators.errorcontrol">error control</link>
120
-
</entry>
121
-
</row>
122
-
<row>
123
-
<entry>left</entry>
124
-
<entry><literal>instanceof</literal></entry>
125
-
<entry>
126
-
<link linkend="language.operators.type">type</link>
127
-
</entry>
128
-
</row>
129
-
<row>
130
-
<entry>(n/a)</entry>
131
-
<entry><literal>!</literal></entry>
132
-
<entry>
133
-
<link linkend="language.operators.logical">logical</link>
134
-
</entry>
135
-
</row>
136
-
<row>
137
-
<entry>left</entry>
138
-
<entry>
139
-
<literal>*</literal>
140
-
<literal>/</literal>
141
-
<literal>%</literal>
142
-
</entry>
143
-
<entry>
144
-
<link linkend="language.operators.arithmetic">arithmetic</link>
145
-
</entry>
146
-
</row>
147
-
<row>
148
-
<entry>left</entry>
149
-
<entry>
150
-
<literal>+</literal>
151
-
<literal>-</literal>
152
-
<literal>.</literal>
153
-
</entry>
154
-
<entry>
155
-
<link linkend="language.operators.arithmetic">arithmetic</link> (binary <literal>+</literal> and <literal>-</literal>),
156
-
<link linkend="language.operators.array">array</link>&listendand;
157
-
<link linkend="language.operators.string">string</link> (<literal>.</literal> prior to PHP 8.0.0)
158
-
</entry>
159
-
</row>
160
-
<row>
161
-
<entry>left</entry>
162
-
<entry>
163
-
<literal>&lt;&lt;</literal>
164
-
<literal>&gt;&gt;</literal>
165
-
</entry>
166
-
<entry>
167
-
<link linkend="language.operators.bitwise">bitwise</link>
168
-
</entry>
169
-
</row>
170
-
<row>
171
-
<entry>left</entry>
172
-
<entry><literal>.</literal></entry>
173
-
<entry>
174
-
<link linkend="language.operators.string">string</link> (as of PHP 8.0.0)
175
-
</entry>
176
-
</row>
177
-
<row>
178
-
<entry>non-associative</entry>
179
-
<entry>
180
-
<literal>&lt;</literal>
181
-
<literal>&lt;=</literal>
182
-
<literal>&gt;</literal>
183
-
<literal>&gt;=</literal>
184
-
</entry>
185
-
<entry>
186
-
<link linkend="language.operators.comparison">comparison</link>
187
-
</entry>
188
-
</row>
189
-
<row>
190
-
<entry>non-associative</entry>
191
-
<entry>
192
-
<literal>==</literal>
193
-
<literal>!=</literal>
194
-
<literal>===</literal>
195
-
<literal>!==</literal>
196
-
<literal>&lt;&gt;</literal>
197
-
<literal>&lt;=&gt;</literal>
198
-
</entry>
199
-
<entry>
200
-
<link linkend="language.operators.comparison">comparison</link>
201
-
</entry>
202
-
</row>
203
-
<row>
204
-
<entry>left</entry>
205
-
<entry><literal>&amp;</literal></entry>
206
-
<entry>
207
-
<link linkend="language.operators.bitwise">bitwise</link>&listendand;
208
-
<link linkend="language.references">references</link></entry>
209
-
</row>
210
-
<row>
211
-
<entry>left</entry>
212
-
<entry><literal>^</literal></entry>
213
-
<entry>
214
-
<link linkend="language.operators.bitwise">bitwise</link>
215
-
</entry>
216
-
</row>
217
-
<row>
218
-
<entry>left</entry>
219
-
<entry><literal>|</literal></entry>
220
-
<entry>
221
-
<link linkend="language.operators.bitwise">bitwise</link>
222
-
</entry>
223
-
</row>
224
-
<row>
225
-
<entry>left</entry>
226
-
<entry><literal>&amp;&amp;</literal></entry>
227
-
<entry>
228
-
<link linkend="language.operators.logical">logical</link>
229
-
</entry>
230
-
</row>
231
-
<row>
232
-
<entry>left</entry>
233
-
<entry><literal>||</literal></entry>
234
-
<entry>
235
-
<link linkend="language.operators.logical">logical</link>
236
-
</entry>
237
-
</row>
238
-
<row>
239
-
<entry>right</entry>
240
-
<entry><literal>??</literal></entry>
241
-
<entry>
242
-
<link linkend="language.operators.comparison.coalesce">null coalescing</link>
243
-
</entry>
244
-
</row>
245
-
<row>
246
-
<entry>non-associative</entry>
247
-
<entry><literal>? :</literal></entry>
248
-
<entry>
249
-
<link linkend="language.operators.comparison.ternary">ternary</link>
250
-
(left-associative prior to PHP 8.0.0)
251
-
</entry>
252
-
</row>
253
-
<row>
254
-
<entry>right</entry>
255
-
<entry>
256
-
<literal>=</literal>
257
-
<literal>+=</literal>
258
-
<literal>-=</literal>
259
-
<literal>*=</literal>
260
-
<literal>**=</literal>
261
-
<literal>/=</literal>
262
-
<literal>.=</literal>
263
-
<literal>%=</literal>
264
-
<literal>&amp;=</literal>
265
-
<literal>|=</literal>
266
-
<literal>^=</literal>
267
-
<literal>&lt;&lt;=</literal>
268
-
<literal>&gt;&gt;=</literal>
269
-
<literal>??=</literal>
270
-
</entry>
271
-
<entry>
272
-
<link linkend="language.operators.assignment">assignment</link>
273
-
</entry>
274
-
</row>
275
-
<row>
276
-
<entry>(n/a)</entry>
277
-
<entry><literal>yield from</literal></entry>
278
-
<entry>
279
-
<link linkend="control-structures.yield.from">yield from</link>
280
-
</entry>
281
-
</row>
282
-
<row>
283
-
<entry>(n/a)</entry>
284
-
<entry><literal>yield</literal></entry>
285
-
<entry>
286
-
<link linkend="control-structures.yield">yield</link>
287
-
</entry>
288
-
</row>
289
-
<row>
290
-
<entry>(n/a)</entry>
291
-
<entry><literal>print</literal></entry>
292
-
<entry><function>print</function></entry>
293
-
</row>
294
-
<row>
295
-
<entry>left</entry>
296
-
<entry><literal>and</literal></entry>
297
-
<entry>
298
-
<link linkend="language.operators.logical">logical</link>
299
-
</entry>
300
-
</row>
301
-
<row>
302
-
<entry>left</entry>
303
-
<entry><literal>xor</literal></entry>
304
-
<entry>
305
-
<link linkend="language.operators.logical">logical</link>
306
-
</entry>
307
-
</row>
308
-
<row>
309
-
<entry>left</entry>
310
-
<entry><literal>or</literal></entry>
311
-
<entry>
312
-
<link linkend="language.operators.logical">logical</link>
313
-
</entry>
314
-
</row>
315
-
</tbody>
316
-
</tgroup>
317
-
</table>
318
-
</para>
319
-
<para>
320
-
<example>
321
-
<title>Associativity</title>
322
-
<programlisting role="php">
323
-
<![CDATA[
324
-
<?php
325
-
$a = 3 * 3 % 5; // (3 * 3) % 5 = 4
326
-
// ternary operator associativity differs from C/C++
327
-
$a = true ? 0 : true ? 1 : 2; // (true ? 0 : true) ? 1 : 2 = 2 (prior to PHP 8.0.0)
328
-

329
-
$a = 1;
330
-
$b = 2;
331
-
$a = $b += 3; // $a = ($b += 3) -> $a = 5, $b = 5
332
-
?>
333
-
]]>
334
-
</programlisting>
335
-
</example>
336
-
</para>
337
-
<para>
338
-
Operator precedence and associativity only determine how expressions
339
-
are grouped, they do not specify an order of evaluation. PHP does not
340
-
(in the general case) specify in which order an expression is evaluated
341
-
and code that assumes a specific order of evaluation should be avoided,
342
-
because the behavior can change between versions of PHP or depending on
343
-
the surrounding code.
344
-
<example>
345
-
<title>Undefined order of evaluation</title>
346
-
<programlisting role="php">
347
-
<![CDATA[
348
-
<?php
349
-
$a = 1;
350
-
echo $a + $a++; // may print either 2 or 3
351
-

352
-
$i = 1;
353
-
$array[$i] = $i++; // may set either index 1 or 2
354
-
?>
355
-
]]>
356
-
</programlisting>
357
-
</example>
358
-
<example>
359
-
<title><literal>+</literal>, <literal>-</literal> and <literal>.</literal> have the same precedence (prior to PHP 8.0.0)</title>
360
-
<programlisting role="php">
361
-
<![CDATA[
362
-
<?php
363
-
$x = 4;
364
-
// this line might result in unexpected output:
365
-
echo "x minus one equals " . $x-1 . ", or so I hope\n";
366
-
// because it is evaluated like this line (prior to PHP 8.0.0):
367
-
echo (("x minus one equals " . $x) - 1) . ", or so I hope\n";
368
-
// the desired precedence can be enforced by using parentheses:
369
-
echo "x minus one equals " . ($x-1) . ", or so I hope\n";
370
-
?>
371
-
]]>
372
-
</programlisting>
373
-
&example.outputs;
374
-
<screen>
375
-
<![CDATA[
376
-
-1, or so I hope
377
-
-1, or so I hope
378
-
x minus one equals 3, or so I hope
379
-
]]>
380
-
</screen>
381
-
</example>
382
-
</para>
383
-
<note>
384
-
<para>
385
-
Although <literal>=</literal> has a lower precedence than
386
-
most other operators, PHP will still allow expressions
387
-
similar to the following: <literal>if (!$a = foo())</literal>,
388
-
in which case the return value of <literal>foo()</literal> is
389
-
put into <varname>$a</varname>.
390
-
</para>
391
-
</note>
392
-
<sect2 role="changelog">
393
-
&reftitle.changelog;
394
-
<informaltable>
395
-
<tgroup cols="2">
396
-
<thead>
397
-
<row>
398
-
<entry>&Version;</entry>
399
-
<entry>&Description;</entry>
400
-
</row>
401
-
</thead>
402
-
<tbody>
403
-
<row>
404
-
<entry>8.0.0</entry>
405
-
<entry>
406
-
String concatenation (<literal>.</literal>) now has a lower precedence than
407
-
arithmetic addition/subtraction (<literal>+</literal> and <literal>-</literal>) and
408
-
bitwise shift left/right (<literal>&lt;&lt;</literal> and <literal>&gt;&gt;</literal>);
409
-
previously it had the same precedence as <literal>+</literal> and <literal>-</literal>
410
-
and a higher precedence than <literal>&lt;&lt;</literal> and <literal>&gt;&gt;</literal>.
411
-
</entry>
412
-
</row>
413
-
<row>
414
-
<entry>8.0.0</entry>
415
-
<entry>
416
-
The ternary operator (<literal>? :</literal>) is non-associative now;
417
-
previously it was left-associative.
418
-
</entry>
419
-
</row>
420
-
<row>
421
-
<entry>7.4.0</entry>
422
-
<entry>
423
-
Relying on the precedence of string concatenation (<literal>.</literal>) relative to
424
-
arithmetic addition/subtraction (<literal>+</literal> or <literal>-</literal>) or
425
-
bitwise shift left/right (<literal>&lt;&lt;</literal> or <literal>&gt;&gt;</literal>),
426
-
i.e. using them together in an unparenthesized expression, is deprecated.
427
-
</entry>
428
-
</row>
429
-
<row>
430
-
<entry>7.4.0</entry>
431
-
<entry>
432
-
Relying on left-associativity of the ternary operator (<literal>? :</literal>),
433
-
i.e. nesting multiple unparenthesized ternary operators, is deprecated.
434
-
</entry>
435
-
</row>
436
-
</tbody>
437
-
</tgroup>
438
-
</informaltable>
439
-
</sect2>
440
-
</sect1>
441
-

442
-
<sect1 xml:id="language.operators.arithmetic">
443
-
<title>Arithmetic Operators</title>
444
-
<simpara>
445
-
Remember basic arithmetic from school? These work just
446
-
like those.
447
-
</simpara>
448
-
<table>
449
-
<title>Arithmetic Operators</title>
450
-
<tgroup cols="3">
451
-
<thead>
452
-
<row>
453
-
<entry>Example</entry>
454
-
<entry>Name</entry>
455
-
<entry>Result</entry>
456
-
</row>
457
-
</thead>
458
-
<tbody>
459
-
<row>
460
-
<entry>+$a</entry>
461
-
<entry>Identity</entry>
462
-
<entry>
463
-
Conversion of <varname>$a</varname> to <type>int</type> or
464
-
<type>float</type> as appropriate.
465
-
</entry>
466
-
</row>
467
-
<row>
468
-
<entry>-$a</entry>
469
-
<entry>Negation</entry>
470
-
<entry>Opposite of <varname>$a</varname>.</entry>
471
-
</row>
472
-
<row>
473
-
<entry>$a + $b</entry>
474
-
<entry>Addition</entry>
475
-
<entry>Sum of <varname>$a</varname> and <varname>$b</varname>.</entry>
476
-
</row>
477
-
<row>
478
-
<entry>$a - $b</entry>
479
-
<entry>Subtraction</entry>
480
-
<entry>Difference of <varname>$a</varname> and <varname>$b</varname>.</entry>
481
-
</row>
482
-
<row>
483
-
<entry>$a * $b</entry>
484
-
<entry>Multiplication</entry>
485
-
<entry>Product of <varname>$a</varname> and <varname>$b</varname>.</entry>
486
-
</row>
487
-
<row>
488
-
<entry>$a / $b</entry>
489
-
<entry>Division</entry>
490
-
<entry>Quotient of <varname>$a</varname> and <varname>$b</varname>.</entry>
491
-
</row>
492
-
<row>
493
-
<entry>$a % $b</entry>
494
-
<entry>Modulo</entry>
495
-
<entry>Remainder of <varname>$a</varname> divided by <varname>$b</varname>.</entry>
496
-
</row>
497
-
<row>
498
-
<entry>$a ** $b</entry>
499
-
<entry>Exponentiation</entry>
500
-
<entry>Result of raising <varname>$a</varname> to the <varname>$b</varname>'th power.</entry>
501
-
</row>
502
-
</tbody>
503
-
</tgroup>
504
-
</table>
505
-
<simpara>
506
-
The division operator ("/") returns a float value unless the two operands
507
-
are integers (or strings that get converted to integers) and the numbers
508
-
are evenly divisible, in which case an integer value will be returned. For
509
-
integer division, see <function>intdiv</function>.
510
-
</simpara>
511
-
<simpara>
512
-
Operands of modulo are converted to <type>int</type>
513
-
before processing. For floating-point modulo, see
514
-
<function>fmod</function>.
515
-
</simpara>
516
-
<para>
517
-
The result of the modulo operator <literal>%</literal> has the same sign
518
-
as the dividend — that is, the result of <literal>$a % $b</literal>
519
-
will have the same sign as <varname>$a</varname>. For example:
520
-
<informalexample>
521
-
<programlisting role="php">
522
-
<![CDATA[
523
-
<?php
524
-

525
-
echo (5 % 3)."\n"; // prints 2
526
-
echo (5 % -3)."\n"; // prints 2
527
-
echo (-5 % 3)."\n"; // prints -2
528
-
echo (-5 % -3)."\n"; // prints -2
529
-

530
-
?>
531
-
]]>
532
-
</programlisting>
533
-
</informalexample>
534
-
</para>
535
-
<sect2 role="seealso">
536
-
&reftitle.seealso;
537
-
<para>
538
-
<simplelist>
539
-
<member><link linkend="ref.math">Math functions</link></member>
540
-
</simplelist>
541
-
</para>
542
-
</sect2>
543
-
</sect1>
544
-

545
-
<sect1 xml:id="language.operators.assignment">
546
-
<title>Assignment Operators</title>
547
-
<simpara>
548
-
The basic assignment operator is "=". Your first inclination might
549
-
be to think of this as "equal to". Don't. It really means that the
550
-
left operand gets set to the value of the expression on the
551
-
right (that is, "gets set to").
552
-
</simpara>
553
-
<para>
554
-
The value of an assignment expression is the value assigned. That
555
-
is, the value of "<literal>$a = 3</literal>" is 3. This allows you to do some tricky
556
-
things:
557
-
<informalexample>
558
-
<programlisting role="php">
559
-
<![CDATA[
560
-
<?php
561
-

562
-
$a = ($b = 4) + 5; // $a is equal to 9 now, and $b has been set to 4.
563
-

564
-
?>
565
-
]]>
566
-
</programlisting>
567
-
</informalexample>
568
-
</para>
569
-
<para>
570
-
In addition to the basic assignment operator, there are "combined
571
-
operators" for all of the <link linkend="language.operators">binary
572
-
arithmetic</link>, array union and string operators that allow you to use a value in an
573
-
expression and then set its value to the result of that expression. For
574
-
example:
575
-
<informalexample>
576
-
<programlisting role="php">
577
-
<![CDATA[
578
-
<?php
579
-

580
-
$a = 3;
581
-
$a += 5; // sets $a to 8, as if we had said: $a = $a + 5;
582
-
$b = "Hello ";
583
-
$b .= "There!"; // sets $b to "Hello There!", just like $b = $b . "There!";
584
-

585
-
?>
586
-
]]>
587
-
</programlisting>
588
-
</informalexample>
589
-
</para>
590
-
<para>
591
-
Note that the assignment copies the original variable to the new
592
-
one (assignment by value), so changes to one will not affect the
593
-
other. This may also have relevance if you need to copy something
594
-
like a large array inside a tight loop.
595
-
</para>
596
-
<para>
597
-
An exception to the usual assignment by value behaviour within PHP occurs
598
-
with <type>object</type>s, which are assigned by reference.
599
-
Objects may be explicitly copied via the <link
600
-
linkend="language.oop5.cloning">clone</link> keyword.
601
-
</para>
602
-

603
-
<sect2 xml:id="language.operators.assignment.reference">
604
-
<title>Assignment by Reference</title>
605
-
<para>
606
-
Assignment by reference is also supported, using the
607
-
"<computeroutput>$var = &amp;$othervar;</computeroutput>" syntax.
608
-
Assignment by reference means that both variables end up pointing at the
609
-
same data, and nothing is copied anywhere.
610
-
</para>
611
-
<para>
612
-
<example>
613
-
<title>Assigning by reference</title>
614
-
<programlisting role="php">
615
-
<![CDATA[
616
-
<?php
617
-
$a = 3;
618
-
$b = &$a; // $b is a reference to $a
619
-

620
-
print "$a\n"; // prints 3
621
-
print "$b\n"; // prints 3
622
-

623
-
$a = 4; // change $a
624
-

625
-
print "$a\n"; // prints 4
626
-
print "$b\n"; // prints 4 as well, since $b is a reference to $a, which has
627
-
// been changed
628
-
?>
629
-
]]>
630
-
</programlisting>
631
-
</example>
632
-
</para>
633
-
<para>
634
-
The <link linkend="language.oop5.basic.new">new</link>
635
-
operator returns a reference automatically, as such assigning the result of
636
-
<link linkend="language.oop5.basic.new">new</link> by reference is an error.
637
-
</para>
638
-
<para>
639
-
<informalexample>
640
-
<programlisting role="php">
641
-
<![CDATA[
642
-
<?php
643
-
class C {}
644
-

645
-
$o = &new C;
646
-
?>
647
-
]]>
648
-
</programlisting>
649
-
&example.outputs;
650
-
<screen>
651
-
<![CDATA[
652
-
Parse error: syntax error, unexpected 'new' (T_NEW) in …
653
-
]]>
654
-
</screen>
655
-
</informalexample>
656
-
</para>
657
-
<para>
658
-
More information on references and their potential uses can be found in
659
-
the <link linkend="language.references">References Explained</link>
660
-
section of the manual.
661
-
</para>
662
-
</sect2>
663
-

664
-
<sect2 xml:id="language.operators.assignment.arithmetic">
665
-
<title>Arithmetic Assignment Operators</title>
666
-
<informaltable>
667
-
<tgroup cols="3">
668
-
<thead>
669
-
<row>
670
-
<entry>Example</entry>
671
-
<entry>Equivalent</entry>
672
-
<entry>Operation</entry>
673
-
</row>
674
-
</thead>
675
-
<tbody>
676
-
<row>
677
-
<entry>$a += $b</entry>
678
-
<entry>$a = $a + $b</entry>
679
-
<entry>Addition</entry>
680
-
</row>
681
-
<row>
682
-
<entry>$a -= $b</entry>
683
-
<entry>$a = $a - $b</entry>
684
-
<entry>Subtraction</entry>
685
-
</row>
686
-
<row>
687
-
<entry>$a *= $b</entry>
688
-
<entry>$a = $a * $b</entry>
689
-
<entry>Multiplication</entry>
690
-
</row>
691
-
<row>
692
-
<entry>$a /= $b</entry>
693
-
<entry>$a = $a / $b</entry>
694
-
<entry>Division</entry>
695
-
</row>
696
-
<row>
697
-
<entry>$a %= $b</entry>
698
-
<entry>$a = $a % $b</entry>
699
-
<entry>Modulus</entry>
700
-
</row>
701
-
<row>
702
-
<entry>$a **= $b</entry>
703
-
<entry>$a = $a ** $b</entry>
704
-
<entry>Exponentiation</entry>
705
-
</row>
706
-
</tbody>
707
-
</tgroup>
708
-
</informaltable>
709
-
</sect2>
710
-

711
-
<sect2 xml:id="language.operators.assignment.bitwise">
712
-
<title>Bitwise Assignment Operators</title>
713
-
<informaltable>
714
-
<tgroup cols="3">
715
-
<thead>
716
-
<row>
717
-
<entry>Example</entry>
718
-
<entry>Equivalent</entry>
719
-
<entry>Operation</entry>
720
-
</row>
721
-
</thead>
722
-
<tbody>
723
-
<row>
724
-
<entry>$a &amp;= $b</entry>
725
-
<entry>$a = $a &amp; $b</entry>
726
-
<entry>Bitwise And</entry>
727
-
</row>
728
-
<row>
729
-
<entry>$a |= $b</entry>
730
-
<entry>$a = $a | $b</entry>
731
-
<entry>Bitwise Or</entry>
732
-
</row>
733
-
<row>
734
-
<entry>$a ^= $b</entry>
735
-
<entry>$a = $a ^ $b</entry>
736
-
<entry>Bitwise Xor</entry>
737
-
</row>
738
-
<row>
739
-
<entry>$a &lt;&lt;= $b</entry>
740
-
<entry>$a = $a &lt;&lt; $b</entry>
741
-
<entry>Left Shift</entry>
742
-
</row>
743
-
<row>
744
-
<entry>$a &gt;&gt;= $b</entry>
745
-
<entry>$a = $a &gt;&gt; $b</entry>
746
-
<entry>Right Shift</entry>
747
-
</row>
748
-
</tbody>
749
-
</tgroup>
750
-
</informaltable>
751
-
</sect2>
752
-

753
-
<sect2 xml:id="language.operators.assignment.other">
754
-
<title>Other Assignment Operators</title>
755
-
<informaltable>
756
-
<tgroup cols="3">
757
-
<thead>
758
-
<row>
759
-
<entry>Example</entry>
760
-
<entry>Equivalent</entry>
761
-
<entry>Operation</entry>
762
-
</row>
763
-
</thead>
764
-
<tbody>
765
-
<row>
766
-
<entry>$a .= $b</entry>
767
-
<entry>$a = $a . $b</entry>
768
-
<entry>String Concatenation</entry>
769
-
</row>
770
-
<row>
771
-
<entry>$a ??= $b</entry>
772
-
<entry>$a = $a ?? $b</entry>
773
-
<entry>Null Coalesce</entry>
774
-
</row>
775
-
</tbody>
776
-
</tgroup>
777
-
</informaltable>
778
-
</sect2>
779
-

780
-
<sect2 role="seealso" xml:id="language.operators.assignment.see-also">
781
-
&reftitle.seealso;
782
-
<para>
783
-
<simplelist>
784
-
<member><link linkend="language.operators.arithmetic">arithmetic operators</link></member>
785
-
<member><link linkend="language.operators.bitwise">bitwise operators</link></member>
786
-
<member><link linkend="language.operators.comparison.coalesce">null coalescing operator</link></member>
787
-
</simplelist>
788
-
</para>
789
-
</sect2>
790
-
</sect1>
791
-

792
-
<sect1 xml:id="language.operators.bitwise">
793
-
<title>Bitwise Operators</title>
794
-
<simpara>
795
-
Bitwise operators allow evaluation and manipulation of specific
796
-
bits within an integer.
797
-
</simpara>
798
-
<table>
799
-
<title>Bitwise Operators</title>
800
-
<tgroup cols="3">
801
-
<thead>
802
-
<row>
803
-
<entry>Example</entry>
804
-
<entry>Name</entry>
805
-
<entry>Result</entry>
806
-
</row>
807
-
</thead>
808
-
<tbody>
809
-
<row>
810
-
<entry><userinput>$a &amp; $b</userinput></entry>
811
-
<entry>And</entry>
812
-
<entry>Bits that are set in both <varname>$a</varname> and <varname>$b</varname> are set.</entry>
813
-
</row>
814
-
<row>
815
-
<entry><userinput>$a | $b</userinput></entry>
816
-
<entry>Or (inclusive or)</entry>
817
-
<entry>Bits that are set in either <varname>$a</varname> or <varname>$b</varname> are set.</entry>
818
-
</row>
819
-
<row>
820
-
<entry><userinput>$a ^ $b</userinput></entry>
821
-
<entry>Xor (exclusive or)</entry>
822
-
<entry>
823
-
Bits that are set in <varname>$a</varname> or <varname>$b</varname> but not both are set.
824
-
</entry>
825
-
</row>
826
-
<row>
827
-
<entry><userinput>~ $a</userinput></entry>
828
-
<entry>Not</entry>
829
-
<entry>
830
-
Bits that are set in <varname>$a</varname> are not set, and vice versa.
831
-
</entry>
832
-
</row>
833
-
<row>
834
-
<entry><userinput>$a &lt;&lt; $b</userinput></entry>
835
-
<entry>Shift left</entry>
836
-
<entry>
837
-
Shift the bits of <varname>$a</varname> <varname>$b</varname> steps to the left (each step means
838
-
"multiply by two")
839
-
</entry>
840
-
</row>
841
-
<row>
842
-
<entry><userinput>$a &gt;&gt; $b</userinput></entry>
843
-
<entry>Shift right</entry>
844
-
<entry>
845
-
Shift the bits of <varname>$a</varname> <varname>$b</varname> steps to the right (each step means
846
-
"divide by two")
847
-
</entry>
848
-
</row>
849
-
</tbody>
850
-
</tgroup>
851
-
</table>
852
-
<para>
853
-
Bit shifting in PHP is arithmetic.
854
-
Bits shifted off either end are discarded.
855
-
Left shifts have zeros shifted in on the right while the sign
856
-
bit is shifted out on the left, meaning the sign of an operand
857
-
is not preserved.
858
-
Right shifts have copies of the sign bit shifted in on the left,
859
-
meaning the sign of an operand is preserved.
860
-
</para>
861
-
<para>
862
-
Use parentheses to ensure the desired
863
-
<link linkend="language.operators.precedence">precedence</link>.
864
-
For example, <literal>$a &amp; $b == true</literal> evaluates
865
-
the equivalency then the bitwise and; while
866
-
<literal>($a &amp; $b) == true</literal> evaluates the bitwise and
867
-
then the equivalency.
868
-
</para>
869
-
<para>
870
-
If both operands for the <literal>&amp;</literal>, <literal>|</literal> and
871
-
<literal>^</literal> operators are strings, then the operation will be
872
-
performed on the ASCII values of the characters that make up the strings and
873
-
the result will be a string. In all other cases, both operands will be
874
-
<link linkend="language.types.integer.casting">converted to integers</link>
875
-
and the result will be an integer.
876
-
</para>
877
-
<para>
878
-
If the operand for the <literal>~</literal> operator is a string, the
879
-
operation will be performed on the ASCII values of the characters that make
880
-
up the string and the result will be a string, otherwise the operand and the
881
-
result will be treated as integers.
882
-
</para>
883
-
<para>
884
-
Both operands and the result for the <literal>&lt;&lt;</literal> and
885
-
<literal>&gt;&gt;</literal> operators are always treated as integers.
886
-
</para>
887
-
<para>
888
-
<informalexample>
889
-
<para>
890
-
<literallayout>
891
-
PHP's error_reporting ini setting uses bitwise values,
892
-
providing a real-world demonstration of turning
893
-
bits off. To show all errors, except for notices,
894
-
the php.ini file instructions say to use:
895
-
<userinput>E_ALL &amp; ~E_NOTICE</userinput>
896
-
</literallayout>
897
-
</para>
898
-
<para>
899
-
<literallayout>
900
-
This works by starting with E_ALL:
901
-
<computeroutput>00000000000000000111011111111111</computeroutput>
902
-
Then taking the value of E_NOTICE...
903
-
<computeroutput>00000000000000000000000000001000</computeroutput>
904
-
... and inverting it via <literal>~</literal>:
905
-
<computeroutput>11111111111111111111111111110111</computeroutput>
906
-
Finally, it uses AND (&amp;) to find the bits turned
907
-
on in both values:
908
-
<computeroutput>00000000000000000111011111110111</computeroutput>
909
-
</literallayout>
910
-
</para>
911
-
<para>
912
-
<literallayout>
913
-
Another way to accomplish that is using XOR (<literal>^</literal>)
914
-
to find bits that are on in only one value or the other:
915
-
<userinput>E_ALL ^ E_NOTICE</userinput>
916
-
</literallayout>
917
-
</para>
918
-
</informalexample>
919
-
</para>
920
-
<para>
921
-
<informalexample>
922
-
<para>
923
-
<literallayout>
924
-
error_reporting can also be used to demonstrate turning bits on.
925
-
The way to show just errors and recoverable errors is:
926
-
<userinput>E_ERROR | E_RECOVERABLE_ERROR</userinput>
927
-
</literallayout>
928
-
</para>
929
-
<para>
930
-
<literallayout>
931
-
This process combines E_ERROR
932
-
<computeroutput>00000000000000000000000000000001</computeroutput>
933
-
and
934
-
<computeroutput>00000000000000000001000000000000</computeroutput>
935
-
using the OR (<literal>|</literal>) operator
936
-
to get the bits turned on in either value:
937
-
<computeroutput>00000000000000000001000000000001</computeroutput>
938
-
</literallayout>
939
-
</para>
940
-
</informalexample>
941
-
</para>
942
-
<para>
943
-
<example>
944
-
<title>Bitwise AND, OR and XOR operations on integers</title>
945
-
<programlisting role="php">
946
-
<![CDATA[
947
-
<?php
948
-
/*
949
-
* Ignore the top section,
950
-
* it is just formatting to make output clearer.
951
-
*/
952
-

953
-
$format = '(%1$2d = %1$04b) = (%2$2d = %2$04b)'
954
-
. ' %3$s (%4$2d = %4$04b)' . "\n";
955
-

956
-
echo <<<EOH
957
-
--------- --------- -- ---------
958
-
result value op test
959
-
--------- --------- -- ---------
960
-
EOH;
961
-

962
-

963
-
/*
964
-
* Here are the examples.
965
-
*/
966
-

967
-
$values = array(0, 1, 2, 4, 8);
968
-
$test = 1 + 4;
969
-

970
-
echo "\n Bitwise AND \n";
971
-
foreach ($values as $value) {
972
-
$result = $value & $test;
973
-
printf($format, $result, $value, '&', $test);
974
-
}
975
-

976
-
echo "\n Bitwise Inclusive OR \n";
977
-
foreach ($values as $value) {
978
-
$result = $value | $test;
979
-
printf($format, $result, $value, '|', $test);
980
-
}
981
-

982
-
echo "\n Bitwise Exclusive OR (XOR) \n";
983
-
foreach ($values as $value) {
984
-
$result = $value ^ $test;
985
-
printf($format, $result, $value, '^', $test);
986
-
}
987
-
?>
988
-
]]>
989
-
</programlisting>
990
-
&example.outputs;
991
-
<screen>
992
-
<![CDATA[
993
-
--------- --------- -- ---------
994
-
result value op test
995
-
--------- --------- -- ---------
996
-
Bitwise AND
997
-
( 0 = 0000) = ( 0 = 0000) & ( 5 = 0101)
998
-
( 1 = 0001) = ( 1 = 0001) & ( 5 = 0101)
999
-
( 0 = 0000) = ( 2 = 0010) & ( 5 = 0101)
1000
-
( 4 = 0100) = ( 4 = 0100) & ( 5 = 0101)
1001
-
( 0 = 0000) = ( 8 = 1000) & ( 5 = 0101)
1002
-

1003
-
Bitwise Inclusive OR
1004
-
( 5 = 0101) = ( 0 = 0000) | ( 5 = 0101)
1005
-
( 5 = 0101) = ( 1 = 0001) | ( 5 = 0101)
1006
-
( 7 = 0111) = ( 2 = 0010) | ( 5 = 0101)
1007
-
( 5 = 0101) = ( 4 = 0100) | ( 5 = 0101)
1008
-
(13 = 1101) = ( 8 = 1000) | ( 5 = 0101)
1009
-

1010
-
Bitwise Exclusive OR (XOR)
1011
-
( 5 = 0101) = ( 0 = 0000) ^ ( 5 = 0101)
1012
-
( 4 = 0100) = ( 1 = 0001) ^ ( 5 = 0101)
1013
-
( 7 = 0111) = ( 2 = 0010) ^ ( 5 = 0101)
1014
-
( 1 = 0001) = ( 4 = 0100) ^ ( 5 = 0101)
1015
-
(13 = 1101) = ( 8 = 1000) ^ ( 5 = 0101)
1016
-
]]>
1017
-
</screen>
1018
-
</example>
1019
-
</para>
1020
-
<para>
1021
-
<example>
1022
-
<title>Bitwise XOR operations on strings</title>
1023
-
<programlisting role="php">
1024
-
<![CDATA[
1025
-
<?php
1026
-
echo 12 ^ 9; // Outputs '5'
1027
-

1028
-
echo "12" ^ "9"; // Outputs the Backspace character (ascii 8)
1029
-
// ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8
1030
-

1031
-
echo "hallo" ^ "hello"; // Outputs the ascii values #0 #4 #0 #0 #0
1032
-
// 'a' ^ 'e' = #4
1033
-

1034
-
echo 2 ^ "3"; // Outputs 1
1035
-
// 2 ^ ((int)"3") == 1
1036
-

1037
-
echo "2" ^ 3; // Outputs 1
1038
-
// ((int)"2") ^ 3 == 1
1039
-
?>
1040
-
]]>
1041
-
</programlisting>
1042
-
</example>
1043
-
</para>
1044
-
<para>
1045
-
<example>
1046
-
<title>Bit shifting on integers</title>
1047
-
<programlisting role="php">
1048
-
<![CDATA[
1049
-
<?php
1050
-
/*
1051
-
* Here are the examples.
1052
-
*/
1053
-

1054
-
echo "\n--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---\n";
1055
-

1056
-
$val = 4;
1057
-
$places = 1;
1058
-
$res = $val >> $places;
1059
-
p($res, $val, '>>', $places, 'copy of sign bit shifted into left side');
1060
-

1061
-
$val = 4;
1062
-
$places = 2;
1063
-
$res = $val >> $places;
1064
-
p($res, $val, '>>', $places);
1065
-

1066
-
$val = 4;
1067
-
$places = 3;
1068
-
$res = $val >> $places;
1069
-
p($res, $val, '>>', $places, 'bits shift out right side');
1070
-

1071
-
$val = 4;
1072
-
$places = 4;
1073
-
$res = $val >> $places;
1074
-
p($res, $val, '>>', $places, 'same result as above; can not shift beyond 0');
1075
-

1076
-

1077
-
echo "\n--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---\n";
1078
-

1079
-
$val = -4;
1080
-
$places = 1;
1081
-
$res = $val >> $places;
1082
-
p($res, $val, '>>', $places, 'copy of sign bit shifted into left side');
1083
-

1084
-
$val = -4;
1085
-
$places = 2;
1086
-
$res = $val >> $places;
1087
-
p($res, $val, '>>', $places, 'bits shift out right side');
1088
-

1089
-
$val = -4;
1090
-
$places = 3;
1091
-
$res = $val >> $places;
1092
-
p($res, $val, '>>', $places, 'same result as above; can not shift beyond -1');
1093
-

1094
-

1095
-
echo "\n--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---\n";
1096
-

1097
-
$val = 4;
1098
-
$places = 1;
1099
-
$res = $val << $places;
1100
-
p($res, $val, '<<', $places, 'zeros fill in right side');
1101
-

1102
-
$val = 4;
1103
-
$places = (PHP_INT_SIZE * 8) - 4;
1104
-
$res = $val << $places;
1105
-
p($res, $val, '<<', $places);
1106
-

1107
-
$val = 4;
1108
-
$places = (PHP_INT_SIZE * 8) - 3;
1109
-
$res = $val << $places;
1110
-
p($res, $val, '<<', $places, 'sign bits get shifted out');
1111
-

1112
-
$val = 4;
1113
-
$places = (PHP_INT_SIZE * 8) - 2;
1114
-
$res = $val << $places;
1115
-
p($res, $val, '<<', $places, 'bits shift out left side');
1116
-

1117
-

1118
-
echo "\n--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---\n";
1119
-

1120
-
$val = -4;
1121
-
$places = 1;
1122
-
$res = $val << $places;
1123
-
p($res, $val, '<<', $places, 'zeros fill in right side');
1124
-

1125
-
$val = -4;
1126
-
$places = (PHP_INT_SIZE * 8) - 3;
1127
-
$res = $val << $places;
1128
-
p($res, $val, '<<', $places);
1129
-

1130
-
$val = -4;
1131
-
$places = (PHP_INT_SIZE * 8) - 2;
1132
-
$res = $val << $places;
1133
-
p($res, $val, '<<', $places, 'bits shift out left side, including sign bit');
1134
-

1135
-

1136
-
/*
1137
-
* Ignore this bottom section,
1138
-
* it is just formatting to make output clearer.
1139
-
*/
1140
-

1141
-
function p($res, $val, $op, $places, $note = '') {
1142
-
$format = '%0' . (PHP_INT_SIZE * 8) . "b\n";
1143
-

1144
-
printf("Expression: %d = %d %s %d\n", $res, $val, $op, $places);
1145
-

1146
-
echo " Decimal:\n";
1147
-
printf(" val=%d\n", $val);
1148
-
printf(" res=%d\n", $res);
1149
-

1150
-
echo " Binary:\n";
1151
-
printf(' val=' . $format, $val);
1152
-
printf(' res=' . $format, $res);
1153
-

1154
-
if ($note) {
1155
-
echo " NOTE: $note\n";
1156
-
}
1157
-

1158
-
echo "\n";
1159
-
}
1160
-
?>
1161
-
]]>
1162
-
</programlisting>
1163
-
&example.outputs.32bit;
1164
-
<screen>
1165
-
<![CDATA[
1166
-

1167
-
--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---
1168
-
Expression: 2 = 4 >> 1
1169
-
Decimal:
1170
-
val=4
1171
-
res=2
1172
-
Binary:
1173
-
val=00000000000000000000000000000100
1174
-
res=00000000000000000000000000000010
1175
-
NOTE: copy of sign bit shifted into left side
1176
-

1177
-
Expression: 1 = 4 >> 2
1178
-
Decimal:
1179
-
val=4
1180
-
res=1
1181
-
Binary:
1182
-
val=00000000000000000000000000000100
1183
-
res=00000000000000000000000000000001
1184
-

1185
-
Expression: 0 = 4 >> 3
1186
-
Decimal:
1187
-
val=4
1188
-
res=0
1189
-
Binary:
1190
-
val=00000000000000000000000000000100
1191
-
res=00000000000000000000000000000000
1192
-
NOTE: bits shift out right side
1193
-

1194
-
Expression: 0 = 4 >> 4
1195
-
Decimal:
1196
-
val=4
1197
-
res=0
1198
-
Binary:
1199
-
val=00000000000000000000000000000100
1200
-
res=00000000000000000000000000000000
1201
-
NOTE: same result as above; can not shift beyond 0
1202
-

1203
-

1204
-
--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---
1205
-
Expression: -2 = -4 >> 1
1206
-
Decimal:
1207
-
val=-4
1208
-
res=-2
1209
-
Binary:
1210
-
val=11111111111111111111111111111100
1211
-
res=11111111111111111111111111111110
1212
-
NOTE: copy of sign bit shifted into left side
1213
-

1214
-
Expression: -1 = -4 >> 2
1215
-
Decimal:
1216
-
val=-4
1217
-
res=-1
1218
-
Binary:
1219
-
val=11111111111111111111111111111100
1220
-
res=11111111111111111111111111111111
1221
-
NOTE: bits shift out right side
1222
-

1223
-
Expression: -1 = -4 >> 3
1224
-
Decimal:
1225
-
val=-4
1226
-
res=-1
1227
-
Binary:
1228
-
val=11111111111111111111111111111100
1229
-
res=11111111111111111111111111111111
1230
-
NOTE: same result as above; can not shift beyond -1
1231
-

1232
-

1233
-
--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---
1234
-
Expression: 8 = 4 << 1
1235
-
Decimal:
1236
-
val=4
1237
-
res=8
1238
-
Binary:
1239
-
val=00000000000000000000000000000100
1240
-
res=00000000000000000000000000001000
1241
-
NOTE: zeros fill in right side
1242
-

1243
-
Expression: 1073741824 = 4 << 28
1244
-
Decimal:
1245
-
val=4
1246
-
res=1073741824
1247
-
Binary:
1248
-
val=00000000000000000000000000000100
1249
-
res=01000000000000000000000000000000
1250
-

1251
-
Expression: -2147483648 = 4 << 29
1252
-
Decimal:
1253
-
val=4
1254
-
res=-2147483648
1255
-
Binary:
1256
-
val=00000000000000000000000000000100
1257
-
res=10000000000000000000000000000000
1258
-
NOTE: sign bits get shifted out
1259
-

1260
-
Expression: 0 = 4 << 30
1261
-
Decimal:
1262
-
val=4
1263
-
res=0
1264
-
Binary:
1265
-
val=00000000000000000000000000000100
1266
-
res=00000000000000000000000000000000
1267
-
NOTE: bits shift out left side
1268
-

1269
-

1270
-
--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---
1271
-
Expression: -8 = -4 << 1
1272
-
Decimal:
1273
-
val=-4
1274
-
res=-8
1275
-
Binary:
1276
-
val=11111111111111111111111111111100
1277
-
res=11111111111111111111111111111000
1278
-
NOTE: zeros fill in right side
1279
-

1280
-
Expression: -2147483648 = -4 << 29
1281
-
Decimal:
1282
-
val=-4
1283
-
res=-2147483648
1284
-
Binary:
1285
-
val=11111111111111111111111111111100
1286
-
res=10000000000000000000000000000000
1287
-

1288
-
Expression: 0 = -4 << 30
1289
-
Decimal:
1290
-
val=-4
1291
-
res=0
1292
-
Binary:
1293
-
val=11111111111111111111111111111100
1294
-
res=00000000000000000000000000000000
1295
-
NOTE: bits shift out left side, including sign bit
1296
-
]]>
1297
-
</screen>
1298
-
&example.outputs.64bit;
1299
-
<screen>
1300
-
<![CDATA[
1301
-

1302
-
--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---
1303
-
Expression: 2 = 4 >> 1
1304
-
Decimal:
1305
-
val=4
1306
-
res=2
1307
-
Binary:
1308
-
val=0000000000000000000000000000000000000000000000000000000000000100
1309
-
res=0000000000000000000000000000000000000000000000000000000000000010
1310
-
NOTE: copy of sign bit shifted into left side
1311
-

1312
-
Expression: 1 = 4 >> 2
1313
-
Decimal:
1314
-
val=4
1315
-
res=1
1316
-
Binary:
1317
-
val=0000000000000000000000000000000000000000000000000000000000000100
1318
-
res=0000000000000000000000000000000000000000000000000000000000000001
1319
-

1320
-
Expression: 0 = 4 >> 3
1321
-
Decimal:
1322
-
val=4
1323
-
res=0
1324
-
Binary:
1325
-
val=0000000000000000000000000000000000000000000000000000000000000100
1326
-
res=0000000000000000000000000000000000000000000000000000000000000000
1327
-
NOTE: bits shift out right side
1328
-

1329
-
Expression: 0 = 4 >> 4
1330
-
Decimal:
1331
-
val=4
1332
-
res=0
1333
-
Binary:
1334
-
val=0000000000000000000000000000000000000000000000000000000000000100
1335
-
res=0000000000000000000000000000000000000000000000000000000000000000
1336
-
NOTE: same result as above; can not shift beyond 0
1337
-

1338
-

1339
-
--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---
1340
-
Expression: -2 = -4 >> 1
1341
-
Decimal:
1342
-
val=-4
1343
-
res=-2
1344
-
Binary:
1345
-
val=1111111111111111111111111111111111111111111111111111111111111100
1346
-
res=1111111111111111111111111111111111111111111111111111111111111110
1347
-
NOTE: copy of sign bit shifted into left side
1348
-

1349
-
Expression: -1 = -4 >> 2
1350
-
Decimal:
1351
-
val=-4
1352
-
res=-1
1353
-
Binary:
1354
-
val=1111111111111111111111111111111111111111111111111111111111111100
1355
-
res=1111111111111111111111111111111111111111111111111111111111111111
1356
-
NOTE: bits shift out right side
1357
-

1358
-
Expression: -1 = -4 >> 3
1359
-
Decimal:
1360
-
val=-4
1361
-
res=-1
1362
-
Binary:
1363
-
val=1111111111111111111111111111111111111111111111111111111111111100
1364
-
res=1111111111111111111111111111111111111111111111111111111111111111
1365
-
NOTE: same result as above; can not shift beyond -1
1366
-

1367
-

1368
-
--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---
1369
-
Expression: 8 = 4 << 1
1370
-
Decimal:
1371
-
val=4
1372
-
res=8
1373
-
Binary:
1374
-
val=0000000000000000000000000000000000000000000000000000000000000100
1375
-
res=0000000000000000000000000000000000000000000000000000000000001000
1376
-
NOTE: zeros fill in right side
1377
-

1378
-
Expression: 4611686018427387904 = 4 << 60
1379
-
Decimal:
1380
-
val=4
1381
-
res=4611686018427387904
1382
-
Binary:
1383
-
val=0000000000000000000000000000000000000000000000000000000000000100
1384
-
res=0100000000000000000000000000000000000000000000000000000000000000
1385
-

1386
-
Expression: -9223372036854775808 = 4 << 61
1387
-
Decimal:
1388
-
val=4
1389
-
res=-9223372036854775808
1390
-
Binary:
1391
-
val=0000000000000000000000000000000000000000000000000000000000000100
1392
-
res=1000000000000000000000000000000000000000000000000000000000000000
1393
-
NOTE: sign bits get shifted out
1394
-

1395
-
Expression: 0 = 4 << 62
1396
-
Decimal:
1397
-
val=4
1398
-
res=0
1399
-
Binary:
1400
-
val=0000000000000000000000000000000000000000000000000000000000000100
1401
-
res=0000000000000000000000000000000000000000000000000000000000000000
1402
-
NOTE: bits shift out left side
1403
-

1404
-

1405
-
--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---
1406
-
Expression: -8 = -4 << 1
1407
-
Decimal:
1408
-
val=-4
1409
-
res=-8
1410
-
Binary:
1411
-
val=1111111111111111111111111111111111111111111111111111111111111100
1412
-
res=1111111111111111111111111111111111111111111111111111111111111000
1413
-
NOTE: zeros fill in right side
1414
-

1415
-
Expression: -9223372036854775808 = -4 << 61
1416
-
Decimal:
1417
-
val=-4
1418
-
res=-9223372036854775808
1419
-
Binary:
1420
-
val=1111111111111111111111111111111111111111111111111111111111111100
1421
-
res=1000000000000000000000000000000000000000000000000000000000000000
1422
-

1423
-
Expression: 0 = -4 << 62
1424
-
Decimal:
1425
-
val=-4
1426
-
res=0
1427
-
Binary:
1428
-
val=1111111111111111111111111111111111111111111111111111111111111100
1429
-
res=0000000000000000000000000000000000000000000000000000000000000000
1430
-
NOTE: bits shift out left side, including sign bit
1431
-
]]>
1432
-
</screen>
1433
-
</example>
1434
-
</para>
1435
-
<warning>
1436
-
<para>
1437
-
Use functions from the <link linkend="book.gmp">gmp</link> extension for
1438
-
bitwise manipulation on numbers beyond <literal>PHP_INT_MAX</literal>.
1439
-
</para>
1440
-
</warning>
1441
-

1442
-
<sect2 role="seealso">
1443
-
&reftitle.seealso;
1444
-
<para>
1445
-
<simplelist>
1446
-
<!-- <link linkend="language.oop5.basic.class.class">::class</link> -->
1447
-
<member><function>pack</function></member>
1448
-
<member><function>unpack</function></member>
1449
-
<member><function>gmp_and</function></member>
1450
-
<member><function>gmp_or</function></member>
1451
-
<member><function>gmp_xor</function></member>
1452
-
<member><function>gmp_testbit</function></member>
1453
-
<member><function>gmp_clrbit</function></member>
1454
-
</simplelist>
1455
-
</para>
1456
-
</sect2>
1457
-
</sect1>
1458
-

1459
-
<sect1 xml:id="language.operators.comparison">
1460
-
<title>Comparison Operators</title>
1461
-
<simpara>
1462
-
Comparison operators, as their name implies, allow you to compare
1463
-
two values. You may also be interested in viewing
1464
-
<link linkend="types.comparisons">the type comparison tables</link>,
1465
-
as they show examples of various type related comparisons.
1466
-
</simpara>
1467
-
<table>
1468
-
<title>Comparison Operators</title>
1469
-
<tgroup cols="3">
1470
-
<thead>
1471
-
<row>
1472
-
<entry>Example</entry>
1473
-
<entry>Name</entry>
1474
-
<entry>Result</entry>
1475
-
</row>
1476
-
</thead>
1477
-
<tbody>
1478
-
<row>
1479
-
<entry>$a == $b</entry>
1480
-
<entry>Equal</entry>
1481
-
<entry>&true; if <varname>$a</varname> is equal to <varname>$b</varname> after type juggling.</entry>
1482
-
</row>
1483
-
<row>
1484
-
<entry>$a === $b</entry>
1485
-
<entry>Identical</entry>
1486
-
<entry>
1487
-
&true; if <varname>$a</varname> is equal to <varname>$b</varname>, and they are of the same
1488
-
type.
1489
-
</entry>
1490
-
</row>
1491
-
<row>
1492
-
<entry>$a != $b</entry>
1493
-
<entry>Not equal</entry>
1494
-
<entry>&true; if <varname>$a</varname> is not equal to <varname>$b</varname> after type juggling.</entry>
1495
-
</row>
1496
-
<row>
1497
-
<entry>$a &lt;&gt; $b</entry>
1498
-
<entry>Not equal</entry>
1499
-
<entry>&true; if <varname>$a</varname> is not equal to <varname>$b</varname> after type juggling.</entry>
1500
-
</row>
1501
-
<row>
1502
-
<entry>$a !== $b</entry>
1503
-
<entry>Not identical</entry>
1504
-
<entry>
1505
-
&true; if <varname>$a</varname> is not equal to <varname>$b</varname>, or they are not of the same
1506
-
type.
1507
-
</entry>
1508
-
</row>
1509
-
<row>
1510
-
<entry>$a &lt; $b</entry>
1511
-
<entry>Less than</entry>
1512
-
<entry>&true; if <varname>$a</varname> is strictly less than <varname>$b</varname>.</entry>
1513
-
</row>
1514
-
<row>
1515
-
<entry>$a &gt; $b</entry>
1516
-
<entry>Greater than</entry>
1517
-
<entry>&true; if <varname>$a</varname> is strictly greater than <varname>$b</varname>.</entry>
1518
-
</row>
1519
-
<row>
1520
-
<entry>$a &lt;= $b</entry>
1521
-
<entry>Less than or equal to </entry>
1522
-
<entry>&true; if <varname>$a</varname> is less than or equal to <varname>$b</varname>.</entry>
1523
-
</row>
1524
-
<row>
1525
-
<entry>$a &gt;= $b</entry>
1526
-
<entry>Greater than or equal to </entry>
1527
-
<entry>&true; if <varname>$a</varname> is greater than or equal to <varname>$b</varname>.</entry>
1528
-
</row>
1529
-
<row>
1530
-
<entry>$a &lt;=&gt; $b</entry>
1531
-
<entry>Spaceship</entry>
1532
-
<entry>
1533
-
An <type>int</type> less than, equal to, or greater than zero when
1534
-
<varname>$a</varname> is less than, equal to, or greater than
1535
-
<varname>$b</varname>, respectively.
1536
-
</entry>
1537
-
</row>
1538
-
</tbody>
1539
-
</tgroup>
1540
-
</table>
1541
-
<para>
1542
-
If both operands are
1543
-
<link linkend="language.types.numeric-strings">numeric strings</link>,
1544
-
or one operand is a number and the other one is a
1545
-
<link linkend="language.types.numeric-strings">numeric string</link>,
1546
-
then the comparison is done numerically.
1547
-
These rules also apply to the
1548
-
<link linkend="control-structures.switch">switch</link> statement.
1549
-
The type conversion does not take place when the comparison is
1550
-
<literal>===</literal> or <literal>!==</literal> as this involves
1551
-
comparing the type as well as the value.
1552
-
</para>
1553
-

1554
-
<warning>
1555
-
<para>
1556
-
Prior to PHP 8.0.0, if a <type>string</type> is compared to a number
1557
-
or a numeric string then the <type>string</type> was converted to a
1558
-
number before performing the comparison. This can lead to surprising
1559
-
results as can be seen with the following example:
1560
-
<informalexample>
1561
-
<programlisting role="php">
1562
-
<![CDATA[
1563
-
<?php
1564
-
var_dump(0 == "a");
1565
-
var_dump("1" == "01");
1566
-
var_dump("10" == "1e1");
1567
-
var_dump(100 == "1e2");
1568
-

1569
-
switch ("a") {
1570
-
case 0:
1571
-
echo "0";
1572
-
break;
1573
-
case "a":
1574
-
echo "a";
1575
-
break;
1576
-
}
1577
-
?>
1578
-
]]>
1579
-
</programlisting>
1580
-
&example.outputs.7;
1581
-
<screen>
1582
-
<![CDATA[
1583
-
bool(true)
1584
-
bool(true)
1585
-
bool(true)
1586
-
bool(true)
1587
-
0
1588
-
]]>
1589
-
</screen>
1590
-
&example.outputs.8;
1591
-
<screen>
1592
-
<![CDATA[
1593
-
bool(false)
1594
-
bool(true)
1595
-
bool(true)
1596
-
bool(true)
1597
-
a
1598
-
]]>
1599
-
</screen>
1600
-
</informalexample>
1601
-
</para>
1602
-
</warning>
1603
-

1604
-
<para>
1605
-
<informalexample>
1606
-
<programlisting role="php">
1607
-
<![CDATA[
1608
-
<?php
1609
-
// Integers
1610
-
echo 1 <=> 1; // 0
1611
-
echo 1 <=> 2; // -1
1612
-
echo 2 <=> 1; // 1
1613
-
1614
-
// Floats
1615
-
echo 1.5 <=> 1.5; // 0
1616
-
echo 1.5 <=> 2.5; // -1
1617
-
echo 2.5 <=> 1.5; // 1
1618
-
1619
-
// Strings
1620
-
echo "a" <=> "a"; // 0
1621
-
echo "a" <=> "b"; // -1
1622
-
echo "b" <=> "a"; // 1
1623
-
1624
-
echo "a" <=> "aa"; // -1
1625
-
echo "zz" <=> "aa"; // 1
1626
-
1627
-
// Arrays
1628
-
echo [] <=> []; // 0
1629
-
echo [1, 2, 3] <=> [1, 2, 3]; // 0
1630
-
echo [1, 2, 3] <=> []; // 1
1631
-
echo [1, 2, 3] <=> [1, 2, 1]; // 1
1632
-
echo [1, 2, 3] <=> [1, 2, 4]; // -1
1633
-
1634
-
// Objects
1635
-
$a = (object) ["a" => "b"];
1636
-
$b = (object) ["a" => "b"];
1637
-
echo $a <=> $b; // 0
1638
-
1639
-
$a = (object) ["a" => "b"];
1640
-
$b = (object) ["a" => "c"];
1641
-
echo $a <=> $b; // -1
1642
-
1643
-
$a = (object) ["a" => "c"];
1644
-
$b = (object) ["a" => "b"];
1645
-
echo $a <=> $b; // 1
1646
-
1647
-
// not only values are compared; keys must match
1648
-
$a = (object) ["a" => "b"];
1649
-
$b = (object) ["b" => "b"];
1650
-
echo $a <=> $b; // 1
1651
-

1652
-
?>
1653
-
]]>
1654
-
1655
-
</programlisting>
1656
-
</informalexample>
1657
-
</para>
1658
-

1659
-
<para>
1660
-
For various types, comparison is done according to the following
1661
-
table (in order).
1662
-
</para>
1663
-
<table xml:id="language.operators.comparison.types">
1664
-
<title>Comparison with Various Types</title>
1665
-
<tgroup cols="3">
1666
-
<thead>
1667
-
<row>
1668
-
<entry>Type of Operand 1</entry>
1669
-
<entry>Type of Operand 2</entry>
1670
-
<entry>Result</entry>
1671
-
</row>
1672
-
</thead>
1673
-
<tbody>
1674
-
<row>
1675
-
<entry><type>null</type> or <type>string</type></entry>
1676
-
<entry><type>string</type></entry>
1677
-
<entry>Convert &null; to "", numerical or lexical comparison</entry>
1678
-
</row>
1679
-
<row>
1680
-
<entry><type>bool</type> or <type>null</type></entry>
1681
-
<entry>anything</entry>
1682
-
<entry>Convert both sides to <type>bool</type>, &false; &lt; &true;</entry>
1683
-
</row>
1684
-
<row>
1685
-
<entry><type>object</type></entry>
1686
-
<entry><type>object</type></entry>
1687
-
<entry>Built-in classes can define its own comparison, different classes
1688
-
are uncomparable, same class see <link
1689
-
linkend="language.oop5.object-comparison">Object Comparison</link>
1690
-
</entry>
1691
-
</row>
1692
-
<row>
1693
-
<entry><type>string</type>, <type>resource</type>, <type>int</type> or <type>float</type></entry>
1694
-
<entry><type>string</type>, <type>resource</type>, <type>int</type> or <type>float</type></entry>
1695
-
<entry>Translate strings and resources to numbers, usual math</entry>
1696
-
</row>
1697
-
<row>
1698
-
<entry><type>array</type></entry>
1699
-
<entry><type>array</type></entry>
1700
-
<entry>Array with fewer members is smaller, if key from operand 1 is not
1701
-
found in operand 2 then arrays are uncomparable, otherwise - compare
1702
-
value by value (see following example)</entry>
1703
-
</row>
1704
-
<row>
1705
-
<entry><type>object</type></entry>
1706
-
<entry>anything</entry>
1707
-
<entry><type>object</type> is always greater</entry>
1708
-
</row>
1709
-
<row>
1710
-
<entry><type>array</type></entry>
1711
-
<entry>anything</entry>
1712
-
<entry><type>array</type> is always greater</entry>
1713
-
</row>
1714
-
</tbody>
1715
-
</tgroup>
1716
-
</table>
1717
-

1718
-
<para>
1719
-
<example>
1720
-
<title>Boolean/null comparison</title>
1721
-
<programlisting role="php">
1722
-
<![CDATA[
1723
-
<?php
1724
-
// Bool and null are compared as bool always
1725
-
var_dump(1 == TRUE); // TRUE - same as (bool)1 == TRUE
1726
-
var_dump(0 == FALSE); // TRUE - same as (bool)0 == FALSE
1727
-
var_dump(100 < TRUE); // FALSE - same as (bool)100 < TRUE
1728
-
var_dump(-10 < FALSE);// FALSE - same as (bool)-10 < FALSE
1729
-
var_dump(min(-100, -10, NULL, 10, 100)); // NULL - (bool)NULL < (bool)-100 is FALSE < TRUE
1730
-
?>
1731
-
]]>
1732
-
</programlisting>
1733
-
</example>
1734
-
</para>
1735
-

1736
-
<para>
1737
-
<example>
1738
-
<title>Transcription of standard array comparison</title>
1739
-
<programlisting role="php">
1740
-
<![CDATA[
1741
-
<?php
1742
-
// Arrays are compared like this with standard comparison operators as well as the spaceship operator.
1743
-
function standard_array_compare($op1, $op2)
1744
-
{
1745
-
if (count($op1) < count($op2)) {
1746
-
return -1; // $op1 < $op2
1747
-
} elseif (count($op1) > count($op2)) {
1748
-
return 1; // $op1 > $op2
1749
-
}
1750
-
foreach ($op1 as $key => $val) {
1751
-
if (!array_key_exists($key, $op2)) {
1752
-
return 1;
1753
-
} elseif ($val < $op2[$key]) {
1754
-
return -1;
1755
-
} elseif ($val > $op2[$key]) {
1756
-
return 1;
1757
-
}
1758
-
}
1759
-
return 0; // $op1 == $op2
1760
-
}
1761
-
?>
1762
-
]]>
1763
-
</programlisting>
1764
-
</example>
1765
-
</para>
1766
-

1767
-
<warning>
1768
-
<title>Comparison of floating point numbers</title>
1769
-

1770
-
<para>
1771
-
Because of the way <type>float</type>s are represented internally, you
1772
-
should not test two <type>float</type>s for equality.
1773
-
</para>
1774
-

1775
-
<para>
1776
-
See the documentation for <type>float</type> for more information.
1777
-
</para>
1778
-
</warning>
1779
-

1780
-
<note>
1781
-
<simpara>
1782
-
Be aware that PHP's type juggling is not always obvious when comparing values of different types,
1783
-
particularly comparing &integer;s to &boolean;s or &integer;s to &string;s. It is therefore generally
1784
-
advisable to use <literal>===</literal> and <literal>!==</literal> comparisons rather than
1785
-
<literal>==</literal> and <literal>!=</literal> in most cases.
1786
-
</simpara>
1787
-
</note>
1788
-

1789
-
<sect2 role="seealso">
1790
-
&reftitle.seealso;
1791
-
<para>
1792
-
<simplelist>
1793
-
<member><function>strcasecmp</function></member>
1794
-
<member><function>strcmp</function></member>
1795
-
<member><link linkend="language.operators.array">Array operators</link></member>
1796
-
<member><link linkend="language.types">Types</link></member>
1797
-
</simplelist>
1798
-
</para>
1799
-
</sect2>
1800
-

1801
-
<sect2 xml:id="language.operators.comparison.ternary">
1802
-
<title>Ternary Operator</title>
1803
-
<para>
1804
-
Another conditional operator is the "?:" (or ternary) operator.
1805
-
<example>
1806
-
<title>Assigning a default value</title>
1807
-
<programlisting role="php">
1808
-
<![CDATA[
1809
-
<?php
1810
-
// Example usage for: Ternary Operator
1811
-
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
1812
-

1813
-
// The above is identical to this if/else statement
1814
-
if (empty($_POST['action'])) {
1815
-
$action = 'default';
1816
-
} else {
1817
-
$action = $_POST['action'];
1818
-
}
1819
-
?>
1820
-
]]>
1821
-
</programlisting>
1822
-
</example>
1823
-
The expression <literal>(expr1) ? (expr2) : (expr3)</literal>
1824
-
evaluates to <replaceable>expr2</replaceable> if
1825
-
<replaceable>expr1</replaceable> evaluates to &true;, and
1826
-
<replaceable>expr3</replaceable> if
1827
-
<replaceable>expr1</replaceable> evaluates to &false;.
1828
-
</para>
1829
-
<para>
1830
-
It is possible to leave out the middle part of the ternary operator.
1831
-
Expression <literal>expr1 ?: expr3</literal> evaluates to
1832
-
the result of <replaceable>expr1</replaceable> if <replaceable>expr1</replaceable>
1833
-
evaluates to &true;, and <replaceable>expr3</replaceable> otherwise.
1834
-
<replaceable>expr1</replaceable> is only evaluated once in this case.
1835
-
</para>
1836
-
<note>
1837
-
<simpara>
1838
-
Please note that the ternary operator is an expression, and that it
1839
-
doesn't evaluate to a variable, but to the result of an expression. This
1840
-
is important to know if you want to return a variable by reference.
1841
-
The statement <literal>return $var == 42 ? $a : $b;</literal> in a
1842
-
return-by-reference function will therefore not work and a warning is
1843
-
issued.
1844
-
</simpara>
1845
-
</note>
1846
-
<note>
1847
-
<para>
1848
-
It is recommended to avoid "stacking" ternary expressions.
1849
-
PHP's behaviour when using more than one unparenthesized ternary operator within a single
1850
-
expression is non-obvious compared to other languages.
1851
-
Indeed prior to PHP 8.0.0, ternary expressions were evaluated left-associative,
1852
-
instead of right-associative like most other programming languages.
1853
-
Relying on left-associativity is deprecated as of PHP 7.4.0.
1854
-
As of PHP 8.0.0, the ternary operator is non-associative.
1855
-
<example>
1856
-
<title>Non-obvious Ternary Behaviour</title>
1857
-
<programlisting role="php">
1858
-
<![CDATA[
1859
-
<?php
1860
-
// on first glance, the following appears to output 'true'
1861
-
echo (true ? 'true' : false ? 't' : 'f');
1862
-

1863
-
// however, the actual output of the above is 't' prior to PHP 8.0.0
1864
-
// this is because ternary expressions are left-associative
1865
-

1866
-
// the following is a more obvious version of the same code as above
1867
-
echo ((true ? 'true' : false) ? 't' : 'f');
1868
-

1869
-
// here, one can see that the first expression is evaluated to 'true', which
1870
-
// in turn evaluates to (bool)true, thus returning the true branch of the
1871
-
// second ternary expression.
1872
-
?>
1873
-
]]>
1874
-
</programlisting>
1875
-
</example>
1876
-
</para>
1877
-
</note>
1878
-
<note>
1879
-
<para>
1880
-
Chaining of short-ternaries (<literal>?:</literal>), however, is stable and behaves reasonably.
1881
-
It will evaluate to the first argument that evaluates to a non-falsy value. Note that undefined
1882
-
values will still raise a warning.
1883
-
<example>
1884
-
<title>Short-ternary chaining</title>
1885
-
<programlisting role="php">
1886
-
<![CDATA[
1887
-
<?php
1888
-
echo 0 ?: 1 ?: 2 ?: 3, PHP_EOL; //1
1889
-
echo 0 ?: 0 ?: 2 ?: 3, PHP_EOL; //2
1890
-
echo 0 ?: 0 ?: 0 ?: 3, PHP_EOL; //3
1891
-
?>
1892
-
]]>
1893
-
</programlisting>
1894
-
</example>
1895
-
</para>
1896
-
</note>
1897
-
</sect2>
1898
-
1899
-
<sect2 xml:id="language.operators.comparison.coalesce">
1900
-
<title>Null Coalescing Operator</title>
1901
-
<para>
1902
-
Another useful shorthand operator is the "??" (or null coalescing) operator.
1903
-
<example>
1904
-
<title>Assigning a default value</title>
1905
-
<programlisting role="php">
1906
-
<![CDATA[
1907
-
<?php
1908
-
// Example usage for: Null Coalesce Operator
1909
-
$action = $_POST['action'] ?? 'default';
1910
-

1911
-
// The above is identical to this if/else statement
1912
-
if (isset($_POST['action'])) {
1913
-
$action = $_POST['action'];
1914
-
} else {
1915
-
$action = 'default';
1916
-
}
1917
-
?>
1918
-
]]>
1919
-
</programlisting>
1920
-
</example>
1921
-
The expression <literal>(expr1) ?? (expr2)</literal> evaluates to
1922
-
<replaceable>expr2</replaceable> if <replaceable>expr1</replaceable> is
1923
-
&null;, and <replaceable>expr1</replaceable> otherwise.
1924
-
</para>
1925
-
<para>
1926
-
In particular, this operator does not emit a notice or warning if the left-hand side
1927
-
value does not exist, just like <function>isset</function>. This is especially
1928
-
useful on array keys.
1929
-
</para>
1930
-
<note>
1931
-
<simpara>
1932
-
Please note that the null coalescing operator is an expression, and that it
1933
-
doesn't evaluate to a variable, but to the result of an expression. This
1934
-
is important to know if you want to return a variable by reference.
1935
-
The statement <literal>return $foo ?? $bar;</literal> in a
1936
-
return-by-reference function will therefore not work and a warning is
1937
-
issued.
1938
-
</simpara>
1939
-
</note>
1940
-
<note>
1941
-
<para>
1942
-
The null coalescing operator has low precedence. That means if mixing it
1943
-
with other operators (such as string concatenation or arithmetic operators)
1944
-
parentheses will likely be required.
1945
-
</para>
1946
-
<programlisting role="php">
1947
-
<![CDATA[
1948
-
<?php
1949
-
// Raises a warning that $name is undefined.
1950
-
print 'Mr. ' . $name ?? 'Anonymous';
1951
-

1952
-
// Prints "Mr. Anonymous"
1953
-
print 'Mr. ' . ($name ?? 'Anonymous');
1954
-
?>
1955
-
]]>
1956
-
</programlisting>
1957
-
</note>
1958
-
<note>
1959
-
<para>
1960
-
Please note that the null coalescing operator allows for simple nesting:
1961
-
<example>
1962
-
<title>Nesting null coalescing operator</title>
1963
-
<programlisting role="php">
1964
-
<![CDATA[
1965
-
<?php
1966
-

1967
-
$foo = null;
1968
-
$bar = null;
1969
-
$baz = 1;
1970
-
$qux = 2;
1971
-

1972
-
echo $foo ?? $bar ?? $baz ?? $qux; // outputs 1
1973
-

1974
-
?>
1975
-
]]>
1976
-
</programlisting>
1977
-
</example>
1978
-
</para>
1979
-
</note>
1980
-
</sect2>
1981
-
</sect1>
1982
-

1983
-
<sect1 xml:id="language.operators.errorcontrol">
1984
-
<title>Error Control Operators</title>
1985
-
<simpara>
1986
-
PHP supports one error control operator: the at sign (<literal>@</literal>).
1987
-
When prepended to an expression in PHP, any diagnostic error that might
1988
-
be generated by that expression will be suppressed.
1989
-
</simpara>
1990
-
<para>
1991
-
If a custom error handler function is set with
1992
-
<function>set_error_handler</function>, it will still be called even though
1993
-
the diagnostic has been suppressed.
1994
-
</para>
1995
-

1996
-
<warning>
1997
-
<para>
1998
-
Prior to PHP 8.0.0, the <function>error_reporting</function> called inside the custom error handler
1999
-
always returned <literal>0</literal> if the error was suppressed by the <literal>@</literal> operator.
2000
-
As of PHP 8.0.0, it returns the value <literal>E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR | E_PARSE</literal>.
2001
-
</para>
2002
-
</warning>
2003
-

2004
-
<simpara>
2005
-
Any error message generated by the expression is available in the <literal>"message"</literal>
2006
-
element of the array returned by <function>error_get_last</function>.
2007
-
The result of that function will change on each error, so it needs to be checked early.
2008
-
</simpara>
2009
-
<para>
2010
-
<informalexample>
2011
-
<programlisting role="php">
2012
-
<![CDATA[
2013
-
<?php
2014
-
/* Intentional file error */
2015
-
$my_file = @file ('non_existent_file') or
2016
-
die ("Failed opening file: error was '" . error_get_last()['message'] . "'");
2017
-

2018
-
// this works for any expression, not just functions:
2019
-
$value = @$cache[$key];
2020
-
// will not issue a notice if the index $key doesn't exist.
2021
-

2022
-
?>
2023
-
]]>
2024
-
</programlisting>
2025
-
</informalexample>
2026
-
</para>
2027
-
<note>
2028
-
<simpara>
2029
-
The <literal>@</literal>-operator works only on
2030
-
<link linkend="language.expressions">expressions</link>.
2031
-
A simple rule of thumb is: if one can take the value of something,
2032
-
then one can prepend the <literal>@</literal> operator to it.
2033
-
For instance, it can be prepended to variables, functions calls,
2034
-
certain language construct calls (e.g. <function>include</function>),
2035
-
and so forth.
2036
-
It cannot be prepended to function or class definitions,
2037
-
or conditional structures such as <literal>if</literal> and
2038
-
&foreach;, and so forth.
2039
-
</simpara>
2040
-
</note>
2041
-
<warning>
2042
-
<para>
2043
-
Prior to PHP 8.0.0, it was possible for the <literal>@</literal> operator
2044
-
to disable critical errors that will terminate script execution.
2045
-
For example, prepending <literal>@</literal> to a call of a function
2046
-
which did not exist, by being unavailable or mistyped, would cause
2047
-
the script to terminate with no indication as to why.
2048
-
</para>
2049
-
</warning>
2050
-

2051
-
<sect2 role="seealso">
2052
-
&reftitle.seealso;
2053
-
<para>
2054
-
<simplelist>
2055
-
<member><function>error_reporting</function></member>
2056
-
<member><link linkend="ref.errorfunc">Error Handling and Logging functions</link></member>
2057
-
</simplelist>
2058
-
</para>
2059
-
</sect2>
2060
-
</sect1>
2061
-

2062
-
<sect1 xml:id="language.operators.execution">
2063
-
<title>Execution Operators</title>
2064
-
<para>
2065
-
PHP supports one execution operator: backticks (``). Note that
2066
-
these are not single-quotes! PHP will attempt to execute the
2067
-
contents of the backticks as a shell command; the output will be
2068
-
returned (i.e., it won't simply be dumped to output; it can be
2069
-
assigned to a variable). Use of the backtick operator is identical
2070
-
to <function>shell_exec</function>.
2071
-
<informalexample>
2072
-
<programlisting role="php">
2073
-
<![CDATA[
2074
-
<?php
2075
-
$output = `ls -al`;
2076
-
echo "<pre>$output</pre>";
2077
-
?>
2078
-
]]>
2079
-
</programlisting>
2080
-
</informalexample>
2081
-
</para>
2082
-
<note>
2083
-
<para>
2084
-
The backtick operator is disabled when
2085
-
<function>shell_exec</function> is disabled.
2086
-
</para>
2087
-
</note>
2088
-
<note>
2089
-
<para>
2090
-
Unlike some other languages, backticks have no special meaning
2091
-
within double-quoted strings.
2092
-
</para>
2093
-
</note>
2094
-

2095
-
<sect2 role="seealso">
2096
-
&reftitle.seealso;
2097
-
<para>
2098
-
<simplelist>
2099
-
<member><link linkend="ref.exec">Program Execution functions</link></member>
2100
-
<member><function>popen</function></member>
2101
-
<member><function>proc_open</function></member>
2102
-
<member><link linkend="features.commandline">Using PHP from the commandline</link></member>
2103
-
</simplelist>
2104
-
</para>
2105
-
</sect2>
2106
-
</sect1>
2107
-

2108
-
<sect1 xml:id="language.operators.increment">
2109
-
<title>Incrementing/Decrementing Operators</title>
2110
-
<para>
2111
-
PHP supports C-style pre- and post-increment and decrement
2112
-
operators.
2113
-
</para>
2114
-
<note>
2115
-
<simpara>
2116
-
The increment/decrement operators only affect numbers and strings.
2117
-
Arrays, objects, booleans and resources are not affected.
2118
-
Decrementing &null; values has no effect too, but incrementing them
2119
-
results in <literal>1</literal>.
2120
-
</simpara>
2121
-
</note>
2122
-
<table>
2123
-
<title>Increment/decrement Operators</title>
2124
-
<tgroup cols="3">
2125
-
<thead>
2126
-
<row>
2127
-
<entry>Example</entry>
2128
-
<entry>Name</entry>
2129
-
<entry>Effect</entry>
2130
-
</row>
2131
-
</thead>
2132
-
<tbody>
2133
-
<row>
2134
-
<entry>++$a</entry>
2135
-
<entry>Pre-increment</entry>
2136
-
<entry>Increments <varname>$a</varname> by one, then returns <varname>$a</varname>.</entry>
2137
-
</row>
2138
-
<row>
2139
-
<entry>$a++</entry>
2140
-
<entry>Post-increment</entry>
2141
-
<entry>Returns <varname>$a</varname>, then increments <varname>$a</varname> by one.</entry>
2142
-
</row>
2143
-
<row>
2144
-
<entry>--$a</entry>
2145
-
<entry>Pre-decrement</entry>
2146
-
<entry>Decrements <varname>$a</varname> by one, then returns <varname>$a</varname>.</entry>
2147
-
</row>
2148
-
<row>
2149
-
<entry>$a--</entry>
2150
-
<entry>Post-decrement</entry>
2151
-
<entry>Returns <varname>$a</varname>, then decrements <varname>$a</varname> by one.</entry>
2152
-
</row>
2153
-
</tbody>
2154
-
</tgroup>
2155
-
</table>
2156
-
<para>
2157
-
Here's a simple example script:
2158
-
<informalexample>
2159
-
<programlisting role="php">
2160
-
<![CDATA[
2161
-
<?php
2162
-
echo "<h3>Postincrement</h3>";
2163
-
$a = 5;
2164
-
echo "Should be 5: " . $a++ . "<br />\n";
2165
-
echo "Should be 6: " . $a . "<br />\n";
2166
-

2167
-
echo "<h3>Preincrement</h3>";
2168
-
$a = 5;
2169
-
echo "Should be 6: " . ++$a . "<br />\n";
2170
-
echo "Should be 6: " . $a . "<br />\n";
2171
-

2172
-
echo "<h3>Postdecrement</h3>";
2173
-
$a = 5;
2174
-
echo "Should be 5: " . $a-- . "<br />\n";
2175
-
echo "Should be 4: " . $a . "<br />\n";
2176
-

2177
-
echo "<h3>Predecrement</h3>";
2178
-
$a = 5;
2179
-
echo "Should be 4: " . --$a . "<br />\n";
2180
-
echo "Should be 4: " . $a . "<br />\n";
2181
-
?>
2182
-
]]>
2183
-
</programlisting>
2184
-
</informalexample>
2185
-
</para>
2186
-
<para>
2187
-
PHP follows Perl's convention when dealing with arithmetic operations
2188
-
on character variables and not C's. For example, in PHP and Perl
2189
-
<literal>$a = 'Z'; $a++;</literal> turns <literal>$a</literal> into <literal>'AA'</literal>, while in C
2190
-
<literal>a = 'Z'; a++;</literal> turns <literal>a</literal> into <literal>'['</literal>
2191
-
(ASCII value of <literal>'Z'</literal> is 90, ASCII value of <literal>'['</literal> is 91).
2192
-
Note that character variables can be incremented but not decremented and
2193
-
even so only plain ASCII alphabets and digits (a-z, A-Z and 0-9) are supported.
2194
-
Incrementing/decrementing other character variables has no effect, the
2195
-
original string is unchanged.
2196
-
<example>
2197
-
<title>Arithmetic Operations on Character Variables</title>
2198
-
<programlisting role="php">
2199
-
<![CDATA[
2200
-
<?php
2201
-
echo '== Alphabets ==' . PHP_EOL;
2202
-
$s = 'W';
2203
-
for ($n=0; $n<6; $n++) {
2204
-
echo ++$s . PHP_EOL;
2205
-
}
2206
-
// Digit characters behave differently
2207
-
echo '== Digits ==' . PHP_EOL;
2208
-
$d = 'A8';
2209
-
for ($n=0; $n<6; $n++) {
2210
-
echo ++$d . PHP_EOL;
2211
-
}
2212
-
$d = 'A08';
2213
-
for ($n=0; $n<6; $n++) {
2214
-
echo ++$d . PHP_EOL;
2215
-
}
2216
-
?>
2217
-
]]>
2218
-
</programlisting>
2219
-
&example.outputs;
2220
-
<screen>
2221
-
<![CDATA[
2222
-
== Characters ==
2223
-
X
2224
-
Y
2225
-
Z
2226
-
AA
2227
-
AB
2228
-
AC
2229
-
== Digits ==
2230
-
A9
2231
-
B0
2232
-
B1
2233
-
B2
2234
-
B3
2235
-
B4
2236
-
A09
2237
-
A10
2238
-
A11
2239
-
A12
2240
-
A13
2241
-
A14
2242
-
]]>
2243
-
</screen>
2244
-
</example>
2245
-
</para>
2246
-
<para>
2247
-
Incrementing or decrementing booleans has no effect.
2248
-
</para>
2249
-
</sect1>
2250
-

2251
-
<sect1 xml:id="language.operators.logical">
2252
-
<title>Logical Operators</title>
2253
-

2254
-
<table>
2255
-
<title>Logical Operators</title>
2256
-
<tgroup cols="3">
2257
-
<thead>
2258
-
<row>
2259
-
<entry>Example</entry>
2260
-
<entry>Name</entry>
2261
-
<entry>Result</entry>
2262
-
</row>
2263
-
</thead>
2264
-
<tbody>
2265
-
<row>
2266
-
<entry>$a and $b</entry>
2267
-
<entry>And</entry>
2268
-
<entry>&true; if both <varname>$a</varname> and <varname>$b</varname> are &true;.</entry>
2269
-
</row>
2270
-
<row>
2271
-
<entry>$a or $b</entry>
2272
-
<entry>Or</entry>
2273
-
<entry>&true; if either <varname>$a</varname> or <varname>$b</varname> is &true;.</entry>
2274
-
</row>
2275
-
<row>
2276
-
<entry>$a xor $b</entry>
2277
-
<entry>Xor</entry>
2278
-
<entry>&true; if either <varname>$a</varname> or <varname>$b</varname> is &true;, but not both.</entry>
2279
-
</row>
2280
-
<row>
2281
-
<entry>! $a</entry>
2282
-
<entry>Not</entry>
2283
-
<entry>&true; if <varname>$a</varname> is not &true;.</entry>
2284
-
</row>
2285
-
<row>
2286
-
<entry>$a &amp;&amp; $b</entry>
2287
-
<entry>And</entry>
2288
-
<entry>&true; if both <varname>$a</varname> and <varname>$b</varname> are &true;.</entry>
2289
-
</row>
2290
-
<row>
2291
-
<entry>$a || $b</entry>
2292
-
<entry>Or</entry>
2293
-
<entry>&true; if either <varname>$a</varname> or <varname>$b</varname> is &true;.</entry>
2294
-
</row>
2295
-
</tbody>
2296
-
</tgroup>
2297
-
</table>
2298
-
<simpara>
2299
-
The reason for the two different variations of "and" and "or"
2300
-
operators is that they operate at different precedences. (See
2301
-
<link linkend="language.operators.precedence">Operator
2302
-
Precedence</link>.)
2303
-
</simpara>
2304
-
<example>
2305
-
<title>Logical operators illustrated</title>
2306
-
<programlisting role="php">
2307
-
<![CDATA[
2308
-
<?php
2309
-

2310
-
// --------------------
2311
-
// foo() will never get called as those operators are short-circuit
2312
-

2313
-
$a = (false && foo());
2314
-
$b = (true || foo());
2315
-
$c = (false and foo());
2316
-
$d = (true or foo());
2317
-

2318
-
// --------------------
2319
-
// "||" has a greater precedence than "or"
2320
-

2321
-
// The result of the expression (false || true) is assigned to $e
2322
-
// Acts like: ($e = (false || true))
2323
-
$e = false || true;
2324
-

2325
-
// The constant false is assigned to $f before the "or" operation occurs
2326
-
// Acts like: (($f = false) or true)
2327
-
$f = false or true;
2328
-

2329
-
var_dump($e, $f);
2330
-

2331
-
// --------------------
2332
-
// "&&" has a greater precedence than "and"
2333
-

2334
-
// The result of the expression (true && false) is assigned to $g
2335
-
// Acts like: ($g = (true && false))
2336
-
$g = true && false;
2337
-

2338
-
// The constant true is assigned to $h before the "and" operation occurs
2339
-
// Acts like: (($h = true) and false)
2340
-
$h = true and false;
2341
-

2342
-
var_dump($g, $h);
2343
-
?>
2344
-
]]>
2345
-
</programlisting>
2346
-
&example.outputs.similar;
2347
-
<screen>
2348
-
<![CDATA[
2349
-
bool(true)
2350
-
bool(false)
2351
-
bool(false)
2352
-
bool(true)
2353
-
]]>
2354
-
</screen>
2355
-
</example>
2356
-
</sect1>
2357
-

2358
-
<sect1 xml:id="language.operators.string">
2359
-
<title>String Operators</title>
2360
-
<simpara>
2361
-
There are two <type>string</type> operators. The first is the
2362
-
concatenation operator ('.'), which returns the concatenation of its
2363
-
right and left arguments. The second is the concatenating assignment
2364
-
operator ('<literal>.=</literal>'), which appends the argument on the right side to
2365
-
the argument on the left side. Please read <link
2366
-
linkend="language.operators.assignment">Assignment
2367
-
Operators</link> for more information.
2368
-
</simpara>
2369
-

2370
-
<para>
2371
-
<informalexample>
2372
-
<programlisting role="php">
2373
-
<![CDATA[
2374
-
<?php
2375
-
$a = "Hello ";
2376
-
$b = $a . "World!"; // now $b contains "Hello World!"
2377
-

2378
-
$a = "Hello ";
2379
-
$a .= "World!"; // now $a contains "Hello World!"
2380
-
?>
2381
-
]]>
2382
-
</programlisting>
2383
-
</informalexample>
2384
-
</para>
2385
-

2386
-
<sect2 role="seealso">
2387
-
&reftitle.seealso;
2388
-
<para>
2389
-
<simplelist>
2390
-
<member><link linkend="language.types.string">String type</link></member>
2391
-
<member><link linkend="ref.strings">String functions</link></member>
2392
-
</simplelist>
2393
-
</para>
2394
-
</sect2>
2395
-
</sect1>
2396
-

2397
-
<sect1 xml:id="language.operators.array">
2398
-
<title>Array Operators</title>
2399
-
<table>
2400
-
<title>Array Operators</title>
2401
-
<tgroup cols="3">
2402
-
<thead>
2403
-
<row>
2404
-
<entry>Example</entry>
2405
-
<entry>Name</entry>
2406
-
<entry>Result</entry>
2407
-
</row>
2408
-
</thead>
2409
-
<tbody>
2410
-
<row>
2411
-
<entry>$a + $b</entry>
2412
-
<entry>Union</entry>
2413
-
<entry>Union of <varname>$a</varname> and <varname>$b</varname>.</entry>
2414
-
</row>
2415
-
<row>
2416
-
<entry>$a == $b</entry>
2417
-
<entry>Equality</entry>
2418
-
<entry>&true; if <varname>$a</varname> and <varname>$b</varname> have the same key/value pairs.</entry>
2419
-
</row>
2420
-
<row>
2421
-
<entry>$a === $b</entry>
2422
-
<entry>Identity</entry>
2423
-
<entry>&true; if <varname>$a</varname> and <varname>$b</varname> have the same key/value pairs in the same
2424
-
order and of the same types.</entry>
2425
-
</row>
2426
-
<row>
2427
-
<entry>$a != $b</entry>
2428
-
<entry>Inequality</entry>
2429
-
<entry>&true; if <varname>$a</varname> is not equal to <varname>$b</varname>.</entry>
2430
-
</row>
2431
-
<row>
2432
-
<entry>$a &lt;&gt; $b</entry>
2433
-
<entry>Inequality</entry>
2434
-
<entry>&true; if <varname>$a</varname> is not equal to <varname>$b</varname>.</entry>
2435
-
</row>
2436
-
<row>
2437
-
<entry>$a !== $b</entry>
2438
-
<entry>Non-identity</entry>
2439
-
<entry>&true; if <varname>$a</varname> is not identical to <varname>$b</varname>.</entry>
2440
-
</row>
2441
-
</tbody>
2442
-
</tgroup>
2443
-
</table>
2444
-
<para>
2445
-
The <literal>+</literal> operator returns the right-hand array appended
2446
-
to the left-hand array; for keys that exist in both arrays, the elements
2447
-
from the left-hand array will be used, and the matching elements from the
2448
-
right-hand array will be ignored.
2449
-
</para>
2450
-
<para>
2451
-
<informalexample>
2452
-
<programlisting role="php">
2453
-
<![CDATA[
2454
-
<?php
2455
-
$a = array("a" => "apple", "b" => "banana");
2456
-
$b = array("a" => "pear", "b" => "strawberry", "c" => "cherry");
2457
-

2458
-
$c = $a + $b; // Union of $a and $b
2459
-
echo "Union of \$a and \$b: \n";
2460
-
var_dump($c);
2461
-

2462
-
$c = $b + $a; // Union of $b and $a
2463
-
echo "Union of \$b and \$a: \n";
2464
-
var_dump($c);
2465
-

2466
-
$a += $b; // Union of $a += $b is $a and $b
2467
-
echo "Union of \$a += \$b: \n";
2468
-
var_dump($a);
2469
-
?>
2470
-
]]>
2471
-
</programlisting>
2472
-
</informalexample>
2473
-
When executed, this script will print the following:
2474
-
<screen role="php">
2475
-
<![CDATA[
2476
-
Union of $a and $b:
2477
-
array(3) {
2478
-
["a"]=>
2479
-
string(5) "apple"
2480
-
["b"]=>
2481
-
string(6) "banana"
2482
-
["c"]=>
2483
-
string(6) "cherry"
2484
-
}
2485
-
Union of $b and $a:
2486
-
array(3) {
2487
-
["a"]=>
2488
-
string(4) "pear"
2489
-
["b"]=>
2490
-
string(10) "strawberry"
2491
-
["c"]=>
2492
-
string(6) "cherry"
2493
-
}
2494
-
Union of $a += $b:
2495
-
array(3) {
2496
-
["a"]=>
2497
-
string(5) "apple"
2498
-
["b"]=>
2499
-
string(6) "banana"
2500
-
["c"]=>
2501
-
string(6) "cherry"
2502
-
}
2503
-
]]>
2504
-
</screen>
2505
-
</para>
2506
-
<para>
2507
-
Elements of arrays are equal for the comparison if they have the
2508
-
same key and value.
2509
-
</para>
2510
-
<para>
2511
-
<example>
2512
-
<title>Comparing arrays</title>
2513
-
<programlisting role="php">
2514
-
<![CDATA[
2515
-
<?php
2516
-
$a = array("apple", "banana");
2517
-
$b = array(1 => "banana", "0" => "apple");
2518
-

2519
-
var_dump($a == $b); // bool(true)
2520
-
var_dump($a === $b); // bool(false)
2521
-
?>
2522
-
]]>
2523
-
</programlisting>
2524
-
</example>
2525
-
</para>
2526
-

2527
-
<sect2 role="seealso">
2528
-
&reftitle.seealso;
2529
-
<para>
2530
-
<simplelist>
2531
-
<member><link linkend="language.types.array">Array type</link></member>
2532
-
<member><link linkend="ref.array">Array functions</link></member>
2533
-
</simplelist>
2534
-
</para>
2535
-
</sect2>
2536
-
</sect1>
2537
-

2538
-
<sect1 xml:id="language.operators.type">
2539
-
<title>Type Operators</title>
2540
-
<para>
2541
-
<literal>instanceof</literal> is used to determine whether a PHP variable
2542
-
is an instantiated object of a certain
2543
-
<link linkend="language.oop5.basic.class">class</link>:
2544
-
<example>
2545
-
<title>Using <literal>instanceof</literal> with classes</title>
2546
-
<programlisting role="php">
2547
-
<![CDATA[
2548
-
<?php
2549
-
class MyClass
2550
-
{
2551
-
}
2552
-

2553
-
class NotMyClass
2554
-
{
2555
-
}
2556
-
$a = new MyClass;
2557
-

2558
-
var_dump($a instanceof MyClass);
2559
-
var_dump($a instanceof NotMyClass);
2560
-
?>
2561
-
]]>
2562
-
</programlisting>
2563
-
&example.outputs;
2564
-
<screen>
2565
-
<![CDATA[
2566
-
bool(true)
2567
-
bool(false)
2568
-
]]>
2569
-
</screen>
2570
-
</example>
2571
-
</para>
2572
-
<para>
2573
-
<literal>instanceof</literal> can also be used to determine whether a variable
2574
-
is an instantiated object of a class that inherits from a parent class:
2575
-
<example>
2576
-
<title>Using <literal>instanceof</literal> with inherited classes</title>
2577
-
<programlisting role="php">
2578
-
<![CDATA[
2579
-
<?php
2580
-
class ParentClass
2581
-
{
2582
-
}
2583
-

2584
-
class MyClass extends ParentClass
2585
-
{
2586
-
}
2587
-

2588
-
$a = new MyClass;
2589
-

2590
-
var_dump($a instanceof MyClass);
2591
-
var_dump($a instanceof ParentClass);
2592
-
?>
2593
-
]]>
2594
-
</programlisting>
2595
-
&example.outputs;
2596
-
<screen>
2597
-
<![CDATA[
2598
-
bool(true)
2599
-
bool(true)
2600
-
]]>
2601
-
</screen>
2602
-
</example>
2603
-
</para>
2604
-
<para>
2605
-
To check if an object is <emphasis>not</emphasis> an instanceof a class, the
2606
-
<link linkend="language.operators.logical">logical <literal>not</literal>
2607
-
operator</link> can be used.
2608
-
<example>
2609
-
<title>Using <literal>instanceof</literal> to check if object is <emphasis>not</emphasis> an
2610
-
instanceof a class</title>
2611
-
<programlisting role="php">
2612
-
<![CDATA[
2613
-
<?php
2614
-
class MyClass
2615
-
{
2616
-
}
2617
-

2618
-
$a = new MyClass;
2619
-
var_dump(!($a instanceof stdClass));
2620
-
?>
2621
-
]]>
2622
-
</programlisting>
2623
-
&example.outputs;
2624
-
<screen>
2625
-
<![CDATA[
2626
-
bool(true)
2627
-
]]>
2628
-
</screen>
2629
-
</example>
2630
-
</para>
2631
-
<para>
2632
-
Lastly, <literal>instanceof</literal> can also be used to determine whether
2633
-
a variable is an instantiated object of a class that implements an
2634
-
<link linkend="language.oop5.interfaces">interface</link>:
2635
-
<example>
2636
-
<title>Using <literal>instanceof</literal> with interfaces</title>
2637
-
<programlisting role="php">
2638
-
<![CDATA[
2639
-
<?php
2640
-
interface MyInterface
2641
-
{
2642
-
}
2643
-

2644
-
class MyClass implements MyInterface
2645
-
{
2646
-
}
2647
-

2648
-
$a = new MyClass;
2649
-

2650
-
var_dump($a instanceof MyClass);
2651
-
var_dump($a instanceof MyInterface);
2652
-
?>
2653
-
]]>
2654
-
</programlisting>
2655
-
&example.outputs;
2656
-
<screen>
2657
-
<![CDATA[
2658
-
bool(true)
2659
-
bool(true)
2660
-
]]>
2661
-
</screen>
2662
-
</example>
2663
-
</para>
2664
-
<para>
2665
-
Although <literal>instanceof</literal> is usually used with a literal classname,
2666
-
it can also be used with another object or a string variable:
2667
-
<example>
2668
-
<title>Using <literal>instanceof</literal> with other variables</title>
2669
-
<programlisting role="php">
2670
-
<![CDATA[
2671
-
<?php
2672
-
interface MyInterface
2673
-
{
2674
-
}
2675
-

2676
-
class MyClass implements MyInterface
2677
-
{
2678
-
}
2679
-

2680
-
$a = new MyClass;
2681
-
$b = new MyClass;
2682
-
$c = 'MyClass';
2683
-
$d = 'NotMyClass';
2684
-

2685
-
var_dump($a instanceof $b); // $b is an object of class MyClass
2686
-
var_dump($a instanceof $c); // $c is a string 'MyClass'
2687
-
var_dump($a instanceof $d); // $d is a string 'NotMyClass'
2688
-
?>
2689
-
]]>
2690
-
</programlisting>
2691
-
&example.outputs;
2692
-
<screen>
2693
-
<![CDATA[
2694
-
bool(true)
2695
-
bool(true)
2696
-
bool(false)
2697
-
]]>
2698
-
</screen>
2699
-
</example>
2700
-
</para>
2701
-
<para>
2702
-
instanceof does not throw any error if the variable being tested is not
2703
-
an object, it simply returns &false;. Constants, however, were not allowed
2704
-
prior to PHP 7.3.0.
2705
-
<example>
2706
-
<title>Using <literal>instanceof</literal> to test other variables</title>
2707
-
<programlisting role="php">
2708
-
<![CDATA[
2709
-
<?php
2710
-
$a = 1;
2711
-
$b = NULL;
2712
-
$c = imagecreate(5, 5);
2713
-
var_dump($a instanceof stdClass); // $a is an integer
2714
-
var_dump($b instanceof stdClass); // $b is NULL
2715
-
var_dump($c instanceof stdClass); // $c is a resource
2716
-
var_dump(FALSE instanceof stdClass);
2717
-
?>
2718
-
]]>
2719
-
</programlisting>
2720
-
&example.outputs;
2721
-
<screen>
2722
-
<![CDATA[
2723
-
bool(false)
2724
-
bool(false)
2725
-
bool(false)
2726
-
PHP Fatal error: instanceof expects an object instance, constant given
2727
-
]]>
2728
-
</screen>
2729
-
</example>
2730
-
</para>
2731
-
<para>
2732
-
As of PHP 7.3.0, constants are allowed on the left-hand-side of the
2733
-
<literal>instanceof</literal> operator.
2734
-
<example>
2735
-
<title>Using <literal>instanceof</literal> to test constants</title>
2736
-
<programlisting role="php">
2737
-
<![CDATA[
2738
-
<?php
2739
-
var_dump(FALSE instanceof stdClass);
2740
-
?>
2741
-
]]>
2742
-
</programlisting>
2743
-
&example.outputs.73;
2744
-
<screen>
2745
-
<![CDATA[
2746
-
bool(false)
2747
-
]]>
2748
-
</screen>
2749
-
</example>
2750
-
</para>
2751
-
<para>
2752
-
As of PHP 8.0.0, <literal>instanceof</literal> can now be used with arbitrary expressions.
2753
-
The expression must be wrapped in parentheses and produce a <type>string</type>.
2754
-
<!-- RFC: https://wiki.php.net/rfc/variable_syntax_tweaks -->
2755
-
<example>
2756
-
<title>Using <literal>instanceof</literal> with an arbitrary expression</title>
2757
-
<programlisting role="php">
2758
-
<![CDATA[
2759
-
<?php
2760
-

2761
-
class ClassA extends \stdClass {}
2762
-
class ClassB extends \stdClass {}
2763
-
class ClassC extends ClassB {}
2764
-
class ClassD extends ClassA {}
2765
-

2766
-
function getSomeClass(): string
2767
-
{
2768
-
return ClassA::class;
2769
-
}
2770
-

2771
-
var_dump(new ClassA instanceof ('std' . 'Class'));
2772
-
var_dump(new ClassB instanceof ('Class' . 'B'));
2773
-
var_dump(new ClassC instanceof ('Class' . 'A'));
2774
-
var_dump(new ClassD instanceof (getSomeClass()));
2775
-
?>
2776
-
]]>
2777
-
</programlisting>
2778
-
&example.outputs.8;
2779
-
<screen>
2780
-
<![CDATA[
2781
-
bool(true)
2782
-
bool(true)
2783
-
bool(false)
2784
-
bool(true)
2785
-
]]>
2786
-
</screen>
2787
-
</example>
2788
-
</para>
2789
-
<simpara>
2790
-
The <literal>instanceof</literal> operator has a functional variant
2791
-
with the <function>is_a</function> function.
2792
-
</simpara>
2793
-

2794
-
<sect2 role="seealso">
2795
-
&reftitle.seealso;
2796
-
<para>
2797
-
<simplelist>
2798
-
<member><function>get_class</function></member>
2799
-
<member><function>is_a</function></member>
2800
-
</simplelist>
2801
-
</para>
2802
-
</sect2>
2803
-
</sect1>
2804
-
</chapter>
2805
-

3
+
<chapter xml:id="language.operators" xmlns="http://docbook.org/ns/docbook">
4
+
<title>Operators</title>
5
+
<simpara>
6
+
An operator is something that takes one or more values (or
7
+
expressions, in programming jargon) and yields another value (so that the
8
+
construction itself becomes an expression).
9
+
</simpara>
10
+
<para>
11
+
Operators can be grouped according to the number of values they take. Unary
12
+
operators take only one value, for example <literal>!</literal> (the
13
+
<link linkend="language.operators.logical">logical not operator</link>) or
14
+
<literal>++</literal> (the
15
+
<link linkend="language.operators.increment">increment operator</link>).
16
+
Binary operators take two values, such as the familiar
17
+
<link linkend="language.operators.arithmetic">arithmetical operators</link>
18
+
<literal>+</literal> (plus) and <literal>-</literal> (minus), and the
19
+
majority of PHP operators fall into this category. Finally, there is a
20
+
single <link linkend="language.operators.comparison.ternary">ternary
21
+
operator</link>, <literal>? :</literal>, which takes three values; this is
22
+
usually referred to simply as "the ternary operator" (although it could
23
+
perhaps more properly be called the conditional operator).
24
+
</para>
25
+
<para>
26
+
A full list of PHP operators follows in the section
27
+
<link linkend="language.operators.precedence">Operator Precedence</link>.
28
+
The section also explains operator precedence and associativity, which govern
29
+
exactly how expressions containing several different operators are
30
+
evaluated.
31
+
</para>
32
+

33
+
&language.operators.precedence;
34
+
&language.operators.arithmetic;
35
+
&language.operators.increment;
36
+
&language.operators.assignment;
37
+
&language.operators.bitwise;
38
+
&language.operators.comparison;
39
+
&language.operators.errorcontrol;
40
+
&language.operators.execution;
41
+
&language.operators.logical;
42
+
&language.operators.string;
43
+
&language.operators.array;
44
+
&language.operators.type;
45
+

46
+
</chapter>
2806
47
<!-- Keep this comment at the end of the file
2807
48
Local variables:
2808
49
mode: sgml
2809
50