language/operators.xml
52407313885d27a4e891e08dd2e2481bcc39e244
...
...
@@ -1,2272 +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 lesser
58
-
precedence than the <literal>&lt;=</literal> operator.
59
-
</para>
60
-
<para>
61
-
Use of parentheses, even when not strictly necessary, can often increase
62
-
readability of the code by making grouping explicit rather than relying
63
-
on the implicit operator precedence and associativity.
64
-
</para>
65
-
<para>
66
-
The following table lists the operators in order of precedence, with
67
-
the highest-precedence ones at the top. Operators on the same line
68
-
have equal precedence, in which case associativity decides grouping.
69
-
<table>
70
-
<title>Operator Precedence</title>
71
-
<tgroup cols="2">
72
-
<thead>
73
-
<row>
74
-
<entry>Associativity</entry>
75
-
<entry>Operators</entry>
76
-
<entry>Additional Information</entry>
77
-
</row>
78
-
</thead>
79
-
<tbody>
80
-
<row>
81
-
<entry>non-associative</entry>
82
-
<entry>
83
-
<literal>clone</literal>
84
-
<literal>new</literal>
85
-
</entry>
86
-
<entry><link linkend="language.oop5.cloning">clone</link> and <link linkend="language.oop5.basic.new">new</link></entry>
87
-
</row>
88
-
<row>
89
-
<entry>left</entry>
90
-
<entry><literal>[</literal></entry>
91
-
<entry><function>array</function></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>right</entry>
100
-
<entry>
101
-
<literal>++</literal>
102
-
<literal>--</literal>
103
-
<literal>~</literal>
104
-
<literal>(int)</literal>
105
-
<literal>(float)</literal>
106
-
<literal>(string)</literal>
107
-
<literal>(array)</literal>
108
-
<literal>(object)</literal>
109
-
<literal>(bool)</literal>
110
-
<literal>@</literal>
111
-
</entry>
112
-
<entry>
113
-
<link linkend="language.types">types</link> and <link linkend="language.operators.increment">increment/decrement</link>
114
-
</entry>
115
-
</row>
116
-
<row>
117
-
<entry>non-associative</entry>
118
-
<entry><literal>instanceof</literal></entry>
119
-
<entry>
120
-
<link linkend="language.types">types</link>
121
-
</entry>
122
-
</row>
123
-
<row>
124
-
<entry>right</entry>
125
-
<entry><literal>!</literal></entry>
126
-
<entry>
127
-
<link linkend="language.operators.logical">logical</link>
128
-
</entry>
129
-
</row>
130
-
<row>
131
-
<entry>left</entry>
132
-
<entry>
133
-
<literal>*</literal>
134
-
<literal>/</literal>
135
-
<literal>%</literal>
136
-
</entry>
137
-
<entry>
138
-
<link linkend="language.operators.arithmetic">arithmetic</link>
139
-
</entry>
140
-
</row>
141
-
<row>
142
-
<entry>left</entry>
143
-
<entry>
144
-
<literal>+</literal>
145
-
<literal>-</literal>
146
-
<literal>.</literal>
147
-
</entry>
148
-
<entry>
149
-
<link linkend="language.operators.arithmetic">arithmetic</link>&listendand;
150
-
<link linkend="language.operators.string">string</link></entry>
151
-
</row>
152
-
<row>
153
-
<entry>left</entry>
154
-
<entry>
155
-
<literal>&lt;&lt;</literal>
156
-
<literal>&gt;&gt;</literal>
157
-
</entry>
158
-
<entry>
159
-
<link linkend="language.operators.bitwise">bitwise</link>
160
-
</entry>
161
-
</row>
162
-
<row>
163
-
<entry>non-associative</entry>
164
-
<entry>
165
-
<literal>&lt;</literal>
166
-
<literal>&lt;=</literal>
167
-
<literal>&gt;</literal>
168
-
<literal>&gt;=</literal>
169
-
</entry>
170
-
<entry>
171
-
<link linkend="language.operators.comparison">comparison</link>
172
-
</entry>
173
-
</row>
174
-
<row>
175
-
<entry>non-associative</entry>
176
-
<entry>
177
-
<literal>==</literal>
178
-
<literal>!=</literal>
179
-
<literal>===</literal>
180
-
<literal>!==</literal>
181
-
<literal>&lt;&gt;</literal>
182
-
</entry>
183
-
<entry>
184
-
<link linkend="language.operators.comparison">comparison</link>
185
-
</entry>
186
-
</row>
187
-
<row>
188
-
<entry>left</entry>
189
-
<entry><literal>&amp;</literal></entry>
190
-
<entry>
191
-
<link linkend="language.operators.bitwise">bitwise</link>&listendand;
192
-
<link linkend="language.references">references</link></entry>
193
-
</row>
194
-
<row>
195
-
<entry>left</entry>
196
-
<entry><literal>^</literal></entry>
197
-
<entry>
198
-
<link linkend="language.operators.bitwise">bitwise</link>
199
-
</entry>
200
-
</row>
201
-
<row>
202
-
<entry>left</entry>
203
-
<entry><literal>|</literal></entry>
204
-
<entry>
205
-
<link linkend="language.operators.bitwise">bitwise</link>
206
-
</entry>
207
-
</row>
208
-
<row>
209
-
<entry>left</entry>
210
-
<entry><literal>&amp;&amp;</literal></entry>
211
-
<entry>
212
-
<link linkend="language.operators.logical">logical</link>
213
-
</entry>
214
-
</row>
215
-
<row>
216
-
<entry>left</entry>
217
-
<entry><literal>||</literal></entry>
218
-
<entry>
219
-
<link linkend="language.operators.logical">logical</link>
220
-
</entry>
221
-
</row>
222
-
<row>
223
-
<entry>left</entry>
224
-
<entry><literal>? :</literal></entry>
225
-
<entry>
226
-
<link linkend="language.operators.comparison.ternary">ternary</link>
227
-
</entry>
228
-
</row>
229
-
<row>
230
-
<entry>right</entry>
231
-
<entry>
232
-
<literal>=</literal>
233
-
<literal>+=</literal>
234
-
<literal>-=</literal>
235
-
<literal>*=</literal>
236
-
<literal>**=</literal>
237
-
<literal>/=</literal>
238
-
<literal>.=</literal>
239
-
<literal>%=</literal>
240
-
<literal>&amp;=</literal>
241
-
<literal>|=</literal>
242
-
<literal>^=</literal>
243
-
<literal>&lt;&lt;=</literal>
244
-
<literal>&gt;&gt;=</literal>
245
-
<literal>=&gt;</literal>
246
-
</entry>
247
-
<entry>
248
-
<link linkend="language.operators.assignment">assignment</link>
249
-
</entry>
250
-
</row>
251
-
<row>
252
-
<entry>left</entry>
253
-
<entry><literal>and</literal></entry>
254
-
<entry>
255
-
<link linkend="language.operators.logical">logical</link>
256
-
</entry>
257
-
</row>
258
-
<row>
259
-
<entry>left</entry>
260
-
<entry><literal>xor</literal></entry>
261
-
<entry>
262
-
<link linkend="language.operators.logical">logical</link>
263
-
</entry>
264
-
</row>
265
-
<row>
266
-
<entry>left</entry>
267
-
<entry><literal>or</literal></entry>
268
-
<entry>
269
-
<link linkend="language.operators.logical">logical</link>
270
-
</entry>
271
-
</row>
272
-
<row>
273
-
<entry>left</entry>
274
-
<entry><literal>,</literal></entry>
275
-
<entry>many uses</entry>
276
-
</row>
277
-
</tbody>
278
-
</tgroup>
279
-
</table>
280
-
</para>
281
-
<para>
282
-
<example>
283
-
<title>Associativity</title>
284
-
<programlisting role="php">
285
-
<![CDATA[
286
-
<?php
287
-
$a = 3 * 3 % 5; // (3 * 3) % 5 = 4
288
-
// ternary operator associativity differs from C/C++
289
-
$a = true ? 0 : true ? 1 : 2; // (true ? 0 : true) ? 1 : 2 = 2
290
-

291
-
$a = 1;
292
-
$b = 2;
293
-
$a = $b += 3; // $a = ($b += 3) -> $a = 5, $b = 5
294
-
?>
295
-
]]>
296
-
</programlisting>
297
-
</example>
298
-
</para>
299
-
<para>
300
-
Operator precedence and associativity only determine how expressions
301
-
are grouped, they do not specify an order of evaluation. PHP does not
302
-
(in the general case) specify in which order an expression is evaluated
303
-
and code that assumes a specific order of evaluation should be avoided,
304
-
because the behavior can change between versions of PHP or depending on
305
-
the surrounding code.
306
-
<example>
307
-
<title>Undefined order of evaluation</title>
308
-
<programlisting role="php">
309
-
<![CDATA[
310
-
<?php
311
-
$a = 1;
312
-
echo $a + $a++; // may print either 2 or 3
313
-

314
-
$i = 1;
315
-
$array[$i] = $i++; // may set either index 1 or 2
316
-
?>
317
-
]]>
318
-
</programlisting>
319
-
</example>
320
-
</para>
321
-
<note>
322
-
<para>
323
-
Although <literal>=</literal> has a lower precedence than
324
-
most other operators, PHP will still allow expressions
325
-
similar to the following: <literal>if (!$a = foo())</literal>,
326
-
in which case the return value of <literal>foo()</literal> is
327
-
put into <varname>$a</varname>.
328
-
</para>
329
-
</note>
330
-
</sect1>
331
-

332
-
<sect1 xml:id="language.operators.arithmetic">
333
-
<title>Arithmetic Operators</title>
334
-
<simpara>
335
-
Remember basic arithmetic from school? These work just
336
-
like those.
337
-
</simpara>
338
-
<table>
339
-
<title>Arithmetic Operators</title>
340
-
<tgroup cols="3">
341
-
<thead>
342
-
<row>
343
-
<entry>Example</entry>
344
-
<entry>Name</entry>
345
-
<entry>Result</entry>
346
-
</row>
347
-
</thead>
348
-
<tbody>
349
-
<row>
350
-
<entry>-$a</entry>
351
-
<entry>Negation</entry>
352
-
<entry>Opposite of <varname>$a</varname>.</entry>
353
-
</row>
354
-
<row>
355
-
<entry>$a + $b</entry>
356
-
<entry>Addition</entry>
357
-
<entry>Sum of <varname>$a</varname> and <varname>$b</varname>.</entry>
358
-
</row>
359
-
<row>
360
-
<entry>$a - $b</entry>
361
-
<entry>Subtraction</entry>
362
-
<entry>Difference of <varname>$a</varname> and <varname>$b</varname>.</entry>
363
-
</row>
364
-
<row>
365
-
<entry>$a * $b</entry>
366
-
<entry>Multiplication</entry>
367
-
<entry>Product of <varname>$a</varname> and <varname>$b</varname>.</entry>
368
-
</row>
369
-
<row>
370
-
<entry>$a / $b</entry>
371
-
<entry>Division</entry>
372
-
<entry>Quotient of <varname>$a</varname> and <varname>$b</varname>.</entry>
373
-
</row>
374
-
<row>
375
-
<entry>$a % $b</entry>
376
-
<entry>Modulus</entry>
377
-
<entry>Remainder of <varname>$a</varname> divided by <varname>$b</varname>.</entry>
378
-
</row>
379
-
<row>
380
-
<entry>$a ** $b</entry>
381
-
<entry>Exponentiation</entry>
382
-
<entry>Result of raising <varname>$a</varname> to the <varname>$b</varname>'th power. Introduced in PHP 5.6.</entry>
383
-
</row>
384
-
</tbody>
385
-
</tgroup>
386
-
</table>
387
-
<simpara>
388
-
The division operator ("/") returns a float value unless the two operands
389
-
are integers (or strings that get converted to integers) and the numbers
390
-
are evenly divisible, in which case an integer value will be returned.
391
-
</simpara>
392
-
<simpara>
393
-
Operands of modulus are converted to integers (by stripping the decimal
394
-
part) before processing.
395
-
</simpara>
396
-
<para>
397
-
The result of the modulus operator <literal>%</literal> has the same sign
398
-
as the dividend — that is, the result of <literal>$a % $b</literal>
399
-
will have the same sign as <varname>$a</varname>. For example:
400
-
<informalexample>
401
-
<programlisting role="php">
402
-
<![CDATA[
403
-
<?php
404
-

405
-
echo (5 % 3)."\n"; // prints 2
406
-
echo (5 % -3)."\n"; // prints 2
407
-
echo (-5 % 3)."\n"; // prints -2
408
-
echo (-5 % -3)."\n"; // prints -2
409
-

410
-
?>
411
-
]]>
412
-
</programlisting>
413
-
</informalexample>
414
-
</para>
415
-
<simpara>
416
-
See also the manual page on
417
-
<link linkend="ref.math">Math functions</link>.
418
-
</simpara>
419
-

420
-
</sect1>
421
-

422
-
<sect1 xml:id="language.operators.assignment">
423
-
<title>Assignment Operators</title>
424
-
<simpara>
425
-
The basic assignment operator is "=". Your first inclination might
426
-
be to think of this as "equal to". Don't. It really means that the
427
-
left operand gets set to the value of the expression on the
428
-
right (that is, "gets set to").
429
-
</simpara>
430
-
<para>
431
-
The value of an assignment expression is the value assigned. That
432
-
is, the value of "<literal>$a = 3</literal>" is 3. This allows you to do some tricky
433
-
things:
434
-
<informalexample>
435
-
<programlisting role="php">
436
-
<![CDATA[
437
-
<?php
438
-

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

441
-
?>
442
-
]]>
443
-
</programlisting>
444
-
</informalexample>
445
-
</para>
446
-
<para>
447
-
For <type>arrays</type>, assigning a value to a named key is performed using
448
-
the "=&gt;" operator. The <link linkend="language.operators.precedence">precedence</link>
449
-
of this operator is the same as other assignment operators.
450
-
</para>
451
-
<para>
452
-
In addition to the basic assignment operator, there are "combined
453
-
operators" for all of the <link linkend="language.operators">binary
454
-
arithmetic</link>, array union and string operators that allow you to use a value in an
455
-
expression and then set its value to the result of that expression. For
456
-
example:
457
-
<informalexample>
458
-
<programlisting role="php">
459
-
<![CDATA[
460
-
<?php
461
-

462
-
$a = 3;
463
-
$a += 5; // sets $a to 8, as if we had said: $a = $a + 5;
464
-
$b = "Hello ";
465
-
$b .= "There!"; // sets $b to "Hello There!", just like $b = $b . "There!";
466
-

467
-
?>
468
-
]]>
469
-
</programlisting>
470
-
</informalexample>
471
-
</para>
472
-
<para>
473
-
Note that the assignment copies the original variable to the new
474
-
one (assignment by value), so changes to one will not affect the
475
-
other. This may also have relevance if you need to copy something
476
-
like a large array inside a tight loop.
477
-
</para>
478
-
<para>
479
-
An exception to the usual assignment by value behaviour within PHP occurs
480
-
with <type>object</type>s, which are assigned by reference in PHP 5.
481
-
Objects may be explicitly copied via the <link
482
-
linkend="language.oop5.cloning">clone</link> keyword.
483
-
</para>
484
-

485
-
<sect2 xml:id="language.operators.assignment.reference">
486
-
<title>Assignment by Reference</title>
487
-
<para>
488
-
Assignment by reference is also supported, using the
489
-
"<computeroutput>$var = &amp;$othervar;</computeroutput>" syntax.
490
-
Assignment by reference means that both variables end up pointing at the
491
-
same data, and nothing is copied anywhere.
492
-
</para>
493
-
<para>
494
-
<example>
495
-
<title>Assigning by reference</title>
496
-
<programlisting role="php">
497
-
<![CDATA[
498
-
<?php
499
-
$a = 3;
500
-
$b = &$a; // $b is a reference to $a
501
-

502
-
print "$a\n"; // prints 3
503
-
print "$b\n"; // prints 3
504
-

505
-
$a = 4; // change $a
506
-

507
-
print "$a\n"; // prints 4
508
-
print "$b\n"; // prints 4 as well, since $b is a reference to $a, which has
509
-
// been changed
510
-
?>
511
-
]]>
512
-
</programlisting>
513
-
</example>
514
-
</para>
515
-
<para>
516
-
As of PHP 5, the <link linkend="language.oop5.basic.new">new</link>
517
-
operator returns a reference automatically, so assigning the result of
518
-
<link linkend="language.oop5.basic.new">new</link> by reference results
519
-
in an <constant>E_DEPRECATED</constant> message in PHP 5.3 and later, and
520
-
an <constant>E_STRICT</constant> message in earlier versions.
521
-
</para>
522
-
<para>
523
-
For example, this code will result in a warning:
524
-
<informalexample>
525
-
<programlisting role="php">
526
-
<![CDATA[
527
-
<?php
528
-
class C {}
529
-

530
-
/* The following line generates the following error message:
531
-
* Deprecated: Assigning the return value of new by reference is deprecated in...
532
-
*/
533
-
$o = &new C;
534
-
?>
535
-
]]>
536
-
</programlisting>
537
-
</informalexample>
538
-
</para>
539
-
<para>
540
-
More information on references and their potential uses can be found in
541
-
the <link linkend="language.references">References Explained</link>
542
-
section of the manual.
543
-
</para>
544
-
</sect2>
545
-
</sect1>
546
-

547
-
<sect1 xml:id="language.operators.bitwise">
548
-
<title>Bitwise Operators</title>
549
-
<simpara>
550
-
Bitwise operators allow evaluation and manipulation of specific
551
-
bits within an integer.
552
-
</simpara>
553
-
<table>
554
-
<title>Bitwise Operators</title>
555
-
<tgroup cols="3">
556
-
<thead>
557
-
<row>
558
-
<entry>Example</entry>
559
-
<entry>Name</entry>
560
-
<entry>Result</entry>
561
-
</row>
562
-
</thead>
563
-
<tbody>
564
-
<row>
565
-
<entry><userinput>$a &amp; $b</userinput></entry>
566
-
<entry>And</entry>
567
-
<entry>Bits that are set in both <varname>$a</varname> and <varname>$b</varname> are set.</entry>
568
-
</row>
569
-
<row>
570
-
<entry><userinput>$a | $b</userinput></entry>
571
-
<entry>Or (inclusive or)</entry>
572
-
<entry>Bits that are set in either <varname>$a</varname> or <varname>$b</varname> are set.</entry>
573
-
</row>
574
-
<row>
575
-
<entry><userinput>$a ^ $b</userinput></entry>
576
-
<entry>Xor (exclusive or)</entry>
577
-
<entry>
578
-
Bits that are set in <varname>$a</varname> or <varname>$b</varname> but not both are set.
579
-
</entry>
580
-
</row>
581
-
<row>
582
-
<entry><userinput>~ $a</userinput></entry>
583
-
<entry>Not</entry>
584
-
<entry>
585
-
Bits that are set in <varname>$a</varname> are not set, and vice versa.
586
-
</entry>
587
-
</row>
588
-
<row>
589
-
<entry><userinput>$a &lt;&lt; $b</userinput></entry>
590
-
<entry>Shift left</entry>
591
-
<entry>
592
-
Shift the bits of <varname>$a</varname> <varname>$b</varname> steps to the left (each step means
593
-
"multiply by two")
594
-
</entry>
595
-
</row>
596
-
<row>
597
-
<entry><userinput>$a &gt;&gt; $b</userinput></entry>
598
-
<entry>Shift right</entry>
599
-
<entry>
600
-
Shift the bits of <varname>$a</varname> <varname>$b</varname> steps to the right (each step means
601
-
"divide by two")
602
-
</entry>
603
-
</row>
604
-
</tbody>
605
-
</tgroup>
606
-
</table>
607
-
<para>
608
-
Bit shifting in PHP is arithmetic.
609
-
Bits shifted off either end are discarded.
610
-
Left shifts have zeros shifted in on the right while the sign
611
-
bit is shifted out on the left, meaning the sign of an operand
612
-
is not preserved.
613
-
Right shifts have copies of the sign bit shifted in on the left,
614
-
meaning the sign of an operand is preserved.
615
-
</para>
616
-
<para>
617
-
Use parentheses to ensure the desired
618
-
<link linkend="language.operators.precedence">precedence</link>.
619
-
For example, <literal>$a &amp; $b == true</literal> evaluates
620
-
the equivalency then the bitwise and; while
621
-
<literal>($a &amp; $b) == true</literal> evaluates the bitwise and
622
-
then the equivalency.
623
-
</para>
624
-
<para>
625
-
If both operands for the <literal>&amp;</literal>, <literal>|</literal> and
626
-
<literal>^</literal> operators are strings, then the operation will be
627
-
performed on the ASCII values of the characters that make up the strings and
628
-
the result will be a string. In all other cases, both operands will be
629
-
<link linkend="language.types.integer.casting">converted to integers</link>
630
-
and the result will be an integer.
631
-
</para>
632
-
<para>
633
-
If the operand for the <literal>~</literal> operator is a string, the
634
-
operation will be performed on the ASCII values of the characters that make
635
-
up the string and the result will be a string, otherwise the operand and the
636
-
result will be treated as integers.
637
-
</para>
638
-
<para>
639
-
Both operands and the result for the <literal>&lt;&lt;</literal> and
640
-
<literal>&gt;&gt;</literal> operators are always treated as integers.
641
-
</para>
642
-
<para>
643
-
<informalexample>
644
-
<para>
645
-
<literallayout>
646
-
PHP's error_reporting ini setting uses bitwise values,
647
-
providing a real-world demonstration of turning
648
-
bits off. To show all errors, except for notices,
649
-
the php.ini file instructions say to use:
650
-
<userinput>E_ALL &amp; ~E_NOTICE</userinput>
651
-
</literallayout>
652
-
</para>
653
-
<para>
654
-
<literallayout>
655
-
This works by starting with E_ALL:
656
-
<computeroutput>00000000000000000111011111111111</computeroutput>
657
-
Then taking the value of E_NOTICE...
658
-
<computeroutput>00000000000000000000000000001000</computeroutput>
659
-
... and inverting it via <literal>~</literal>:
660
-
<computeroutput>11111111111111111111111111110111</computeroutput>
661
-
Finally, it uses AND (&amp;) to find the bits turned
662
-
on in both values:
663
-
<computeroutput>00000000000000000111011111110111</computeroutput>
664
-
</literallayout>
665
-
</para>
666
-
<para>
667
-
<literallayout>
668
-
Another way to accomplish that is using XOR (<literal>^</literal>)
669
-
to find bits that are on in only one value or the other:
670
-
<userinput>E_ALL ^ E_NOTICE</userinput>
671
-
</literallayout>
672
-
</para>
673
-
</informalexample>
674
-
</para>
675
-
<para>
676
-
<informalexample>
677
-
<para>
678
-
<literallayout>
679
-
error_reporting can also be used to demonstrate turning bits on.
680
-
The way to show just errors and recoverable errors is:
681
-
<userinput>E_ERROR | E_RECOVERABLE_ERROR</userinput>
682
-
</literallayout>
683
-
</para>
684
-
<para>
685
-
<literallayout>
686
-
This process combines E_ERROR
687
-
<computeroutput>00000000000000000000000000000001</computeroutput>
688
-
and
689
-
<computeroutput>00000000000000000001000000000000</computeroutput>
690
-
using the OR (<literal>|</literal>) operator
691
-
to get the bits turned on in either value:
692
-
<computeroutput>00000000000000000001000000000001</computeroutput>
693
-
</literallayout>
694
-
</para>
695
-
</informalexample>
696
-
</para>
697
-
<para>
698
-
<example>
699
-
<title>Bitwise AND, OR and XOR operations on integers</title>
700
-
<programlisting role="php">
701
-
<![CDATA[
702
-
<?php
703
-
/*
704
-
* Ignore the top section,
705
-
* it is just formatting to make output clearer.
706
-
*/
707
-

708
-
$format = '(%1$2d = %1$04b) = (%2$2d = %2$04b)'
709
-
. ' %3$s (%4$2d = %4$04b)' . "\n";
710
-

711
-
echo <<<EOH
712
-
--------- --------- -- ---------
713
-
result value op test
714
-
--------- --------- -- ---------
715
-
EOH;
716
-

717
-

718
-
/*
719
-
* Here are the examples.
720
-
*/
721
-

722
-
$values = array(0, 1, 2, 4, 8);
723
-
$test = 1 + 4;
724
-

725
-
echo "\n Bitwise AND \n";
726
-
foreach ($values as $value) {
727
-
$result = $value & $test;
728
-
printf($format, $result, $value, '&', $test);
729
-
}
730
-

731
-
echo "\n Bitwise Inclusive OR \n";
732
-
foreach ($values as $value) {
733
-
$result = $value | $test;
734
-
printf($format, $result, $value, '|', $test);
735
-
}
736
-

737
-
echo "\n Bitwise Exclusive OR (XOR) \n";
738
-
foreach ($values as $value) {
739
-
$result = $value ^ $test;
740
-
printf($format, $result, $value, '^', $test);
741
-
}
742
-
?>
743
-
]]>
744
-
</programlisting>
745
-
&example.outputs;
746
-
<screen>
747
-
<![CDATA[
748
-
--------- --------- -- ---------
749
-
result value op test
750
-
--------- --------- -- ---------
751
-
Bitwise AND
752
-
( 0 = 0000) = ( 0 = 0000) & ( 5 = 0101)
753
-
( 1 = 0001) = ( 1 = 0001) & ( 5 = 0101)
754
-
( 0 = 0000) = ( 2 = 0010) & ( 5 = 0101)
755
-
( 4 = 0100) = ( 4 = 0100) & ( 5 = 0101)
756
-
( 0 = 0000) = ( 8 = 1000) & ( 5 = 0101)
757
-

758
-
Bitwise Inclusive OR
759
-
( 5 = 0101) = ( 0 = 0000) | ( 5 = 0101)
760
-
( 5 = 0101) = ( 1 = 0001) | ( 5 = 0101)
761
-
( 7 = 0111) = ( 2 = 0010) | ( 5 = 0101)
762
-
( 5 = 0101) = ( 4 = 0100) | ( 5 = 0101)
763
-
(13 = 1101) = ( 8 = 1000) | ( 5 = 0101)
764
-

765
-
Bitwise Exclusive OR (XOR)
766
-
( 5 = 0101) = ( 0 = 0000) ^ ( 5 = 0101)
767
-
( 4 = 0100) = ( 1 = 0001) ^ ( 5 = 0101)
768
-
( 7 = 0111) = ( 2 = 0010) ^ ( 5 = 0101)
769
-
( 1 = 0001) = ( 4 = 0100) ^ ( 5 = 0101)
770
-
(13 = 1101) = ( 8 = 1000) ^ ( 5 = 0101)
771
-
]]>
772
-
</screen>
773
-
</example>
774
-
</para>
775
-
<para>
776
-
<example>
777
-
<title>Bitwise XOR operations on strings</title>
778
-
<programlisting role="php">
779
-
<![CDATA[
780
-
<?php
781
-
echo 12 ^ 9; // Outputs '5'
782
-

783
-
echo "12" ^ "9"; // Outputs the Backspace character (ascii 8)
784
-
// ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8
785
-

786
-
echo "hallo" ^ "hello"; // Outputs the ascii values #0 #4 #0 #0 #0
787
-
// 'a' ^ 'e' = #4
788
-

789
-
echo 2 ^ "3"; // Outputs 1
790
-
// 2 ^ ((int)"3") == 1
791
-

792
-
echo "2" ^ 3; // Outputs 1
793
-
// ((int)"2") ^ 3 == 1
794
-
?>
795
-
]]>
796
-
</programlisting>
797
-
</example>
798
-
</para>
799
-
<para>
800
-
<example>
801
-
<title>Bit shifting on integers</title>
802
-
<programlisting role="php">
803
-
<![CDATA[
804
-
<?php
805
-
/*
806
-
* Here are the examples.
807
-
*/
808
-

809
-
echo "\n--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---\n";
810
-

811
-
$val = 4;
812
-
$places = 1;
813
-
$res = $val >> $places;
814
-
p($res, $val, '>>', $places, 'copy of sign bit shifted into left side');
815
-

816
-
$val = 4;
817
-
$places = 2;
818
-
$res = $val >> $places;
819
-
p($res, $val, '>>', $places);
820
-

821
-
$val = 4;
822
-
$places = 3;
823
-
$res = $val >> $places;
824
-
p($res, $val, '>>', $places, 'bits shift out right side');
825
-

826
-
$val = 4;
827
-
$places = 4;
828
-
$res = $val >> $places;
829
-
p($res, $val, '>>', $places, 'same result as above; can not shift beyond 0');
830
-

831
-

832
-
echo "\n--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---\n";
833
-

834
-
$val = -4;
835
-
$places = 1;
836
-
$res = $val >> $places;
837
-
p($res, $val, '>>', $places, 'copy of sign bit shifted into left side');
838
-

839
-
$val = -4;
840
-
$places = 2;
841
-
$res = $val >> $places;
842
-
p($res, $val, '>>', $places, 'bits shift out right side');
843
-

844
-
$val = -4;
845
-
$places = 3;
846
-
$res = $val >> $places;
847
-
p($res, $val, '>>', $places, 'same result as above; can not shift beyond -1');
848
-

849
-

850
-
echo "\n--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---\n";
851
-

852
-
$val = 4;
853
-
$places = 1;
854
-
$res = $val << $places;
855
-
p($res, $val, '<<', $places, 'zeros fill in right side');
856
-

857
-
$val = 4;
858
-
$places = (PHP_INT_SIZE * 8) - 4;
859
-
$res = $val << $places;
860
-
p($res, $val, '<<', $places);
861
-

862
-
$val = 4;
863
-
$places = (PHP_INT_SIZE * 8) - 3;
864
-
$res = $val << $places;
865
-
p($res, $val, '<<', $places, 'sign bits get shifted out');
866
-

867
-
$val = 4;
868
-
$places = (PHP_INT_SIZE * 8) - 2;
869
-
$res = $val << $places;
870
-
p($res, $val, '<<', $places, 'bits shift out left side');
871
-

872
-

873
-
echo "\n--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---\n";
874
-

875
-
$val = -4;
876
-
$places = 1;
877
-
$res = $val << $places;
878
-
p($res, $val, '<<', $places, 'zeros fill in right side');
879
-

880
-
$val = -4;
881
-
$places = (PHP_INT_SIZE * 8) - 3;
882
-
$res = $val << $places;
883
-
p($res, $val, '<<', $places);
884
-

885
-
$val = -4;
886
-
$places = (PHP_INT_SIZE * 8) - 2;
887
-
$res = $val << $places;
888
-
p($res, $val, '<<', $places, 'bits shift out left side, including sign bit');
889
-

890
-

891
-
/*
892
-
* Ignore this bottom section,
893
-
* it is just formatting to make output clearer.
894
-
*/
895
-

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

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

901
-
echo " Decimal:\n";
902
-
printf(" val=%d\n", $val);
903
-
printf(" res=%d\n", $res);
904
-

905
-
echo " Binary:\n";
906
-
printf(' val=' . $format, $val);
907
-
printf(' res=' . $format, $res);
908
-

909
-
if ($note) {
910
-
echo " NOTE: $note\n";
911
-
}
912
-

913
-
echo "\n";
914
-
}
915
-
?>
916
-
]]>
917
-
</programlisting>
918
-
&example.outputs.32bit;
919
-
<screen>
920
-
<![CDATA[
921
-

922
-
--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---
923
-
Expression: 2 = 4 >> 1
924
-
Decimal:
925
-
val=4
926
-
res=2
927
-
Binary:
928
-
val=00000000000000000000000000000100
929
-
res=00000000000000000000000000000010
930
-
NOTE: copy of sign bit shifted into left side
931
-

932
-
Expression: 1 = 4 >> 2
933
-
Decimal:
934
-
val=4
935
-
res=1
936
-
Binary:
937
-
val=00000000000000000000000000000100
938
-
res=00000000000000000000000000000001
939
-

940
-
Expression: 0 = 4 >> 3
941
-
Decimal:
942
-
val=4
943
-
res=0
944
-
Binary:
945
-
val=00000000000000000000000000000100
946
-
res=00000000000000000000000000000000
947
-
NOTE: bits shift out right side
948
-

949
-
Expression: 0 = 4 >> 4
950
-
Decimal:
951
-
val=4
952
-
res=0
953
-
Binary:
954
-
val=00000000000000000000000000000100
955
-
res=00000000000000000000000000000000
956
-
NOTE: same result as above; can not shift beyond 0
957
-

958
-

959
-
--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---
960
-
Expression: -2 = -4 >> 1
961
-
Decimal:
962
-
val=-4
963
-
res=-2
964
-
Binary:
965
-
val=11111111111111111111111111111100
966
-
res=11111111111111111111111111111110
967
-
NOTE: copy of sign bit shifted into left side
968
-

969
-
Expression: -1 = -4 >> 2
970
-
Decimal:
971
-
val=-4
972
-
res=-1
973
-
Binary:
974
-
val=11111111111111111111111111111100
975
-
res=11111111111111111111111111111111
976
-
NOTE: bits shift out right side
977
-

978
-
Expression: -1 = -4 >> 3
979
-
Decimal:
980
-
val=-4
981
-
res=-1
982
-
Binary:
983
-
val=11111111111111111111111111111100
984
-
res=11111111111111111111111111111111
985
-
NOTE: same result as above; can not shift beyond -1
986
-

987
-

988
-
--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---
989
-
Expression: 8 = 4 << 1
990
-
Decimal:
991
-
val=4
992
-
res=8
993
-
Binary:
994
-
val=00000000000000000000000000000100
995
-
res=00000000000000000000000000001000
996
-
NOTE: zeros fill in right side
997
-

998
-
Expression: 1073741824 = 4 << 28
999
-
Decimal:
1000
-
val=4
1001
-
res=1073741824
1002
-
Binary:
1003
-
val=00000000000000000000000000000100
1004
-
res=01000000000000000000000000000000
1005
-

1006
-
Expression: -2147483648 = 4 << 29
1007
-
Decimal:
1008
-
val=4
1009
-
res=-2147483648
1010
-
Binary:
1011
-
val=00000000000000000000000000000100
1012
-
res=10000000000000000000000000000000
1013
-
NOTE: sign bits get shifted out
1014
-

1015
-
Expression: 0 = 4 << 30
1016
-
Decimal:
1017
-
val=4
1018
-
res=0
1019
-
Binary:
1020
-
val=00000000000000000000000000000100
1021
-
res=00000000000000000000000000000000
1022
-
NOTE: bits shift out left side
1023
-

1024
-

1025
-
--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---
1026
-
Expression: -8 = -4 << 1
1027
-
Decimal:
1028
-
val=-4
1029
-
res=-8
1030
-
Binary:
1031
-
val=11111111111111111111111111111100
1032
-
res=11111111111111111111111111111000
1033
-
NOTE: zeros fill in right side
1034
-

1035
-
Expression: -2147483648 = -4 << 29
1036
-
Decimal:
1037
-
val=-4
1038
-
res=-2147483648
1039
-
Binary:
1040
-
val=11111111111111111111111111111100
1041
-
res=10000000000000000000000000000000
1042
-

1043
-
Expression: 0 = -4 << 30
1044
-
Decimal:
1045
-
val=-4
1046
-
res=0
1047
-
Binary:
1048
-
val=11111111111111111111111111111100
1049
-
res=00000000000000000000000000000000
1050
-
NOTE: bits shift out left side, including sign bit
1051
-
]]>
1052
-
</screen>
1053
-
&example.outputs.64bit;
1054
-
<screen>
1055
-
<![CDATA[
1056
-

1057
-
--- BIT SHIFT RIGHT ON POSITIVE INTEGERS ---
1058
-
Expression: 2 = 4 >> 1
1059
-
Decimal:
1060
-
val=4
1061
-
res=2
1062
-
Binary:
1063
-
val=0000000000000000000000000000000000000000000000000000000000000100
1064
-
res=0000000000000000000000000000000000000000000000000000000000000010
1065
-
NOTE: copy of sign bit shifted into left side
1066
-

1067
-
Expression: 1 = 4 >> 2
1068
-
Decimal:
1069
-
val=4
1070
-
res=1
1071
-
Binary:
1072
-
val=0000000000000000000000000000000000000000000000000000000000000100
1073
-
res=0000000000000000000000000000000000000000000000000000000000000001
1074
-

1075
-
Expression: 0 = 4 >> 3
1076
-
Decimal:
1077
-
val=4
1078
-
res=0
1079
-
Binary:
1080
-
val=0000000000000000000000000000000000000000000000000000000000000100
1081
-
res=0000000000000000000000000000000000000000000000000000000000000000
1082
-
NOTE: bits shift out right side
1083
-

1084
-
Expression: 0 = 4 >> 4
1085
-
Decimal:
1086
-
val=4
1087
-
res=0
1088
-
Binary:
1089
-
val=0000000000000000000000000000000000000000000000000000000000000100
1090
-
res=0000000000000000000000000000000000000000000000000000000000000000
1091
-
NOTE: same result as above; can not shift beyond 0
1092
-

1093
-

1094
-
--- BIT SHIFT RIGHT ON NEGATIVE INTEGERS ---
1095
-
Expression: -2 = -4 >> 1
1096
-
Decimal:
1097
-
val=-4
1098
-
res=-2
1099
-
Binary:
1100
-
val=1111111111111111111111111111111111111111111111111111111111111100
1101
-
res=1111111111111111111111111111111111111111111111111111111111111110
1102
-
NOTE: copy of sign bit shifted into left side
1103
-

1104
-
Expression: -1 = -4 >> 2
1105
-
Decimal:
1106
-
val=-4
1107
-
res=-1
1108
-
Binary:
1109
-
val=1111111111111111111111111111111111111111111111111111111111111100
1110
-
res=1111111111111111111111111111111111111111111111111111111111111111
1111
-
NOTE: bits shift out right side
1112
-

1113
-
Expression: -1 = -4 >> 3
1114
-
Decimal:
1115
-
val=-4
1116
-
res=-1
1117
-
Binary:
1118
-
val=1111111111111111111111111111111111111111111111111111111111111100
1119
-
res=1111111111111111111111111111111111111111111111111111111111111111
1120
-
NOTE: same result as above; can not shift beyond -1
1121
-

1122
-

1123
-
--- BIT SHIFT LEFT ON POSITIVE INTEGERS ---
1124
-
Expression: 8 = 4 << 1
1125
-
Decimal:
1126
-
val=4
1127
-
res=8
1128
-
Binary:
1129
-
val=0000000000000000000000000000000000000000000000000000000000000100
1130
-
res=0000000000000000000000000000000000000000000000000000000000001000
1131
-
NOTE: zeros fill in right side
1132
-

1133
-
Expression: 4611686018427387904 = 4 << 60
1134
-
Decimal:
1135
-
val=4
1136
-
res=4611686018427387904
1137
-
Binary:
1138
-
val=0000000000000000000000000000000000000000000000000000000000000100
1139
-
res=0100000000000000000000000000000000000000000000000000000000000000
1140
-

1141
-
Expression: -9223372036854775808 = 4 << 61
1142
-
Decimal:
1143
-
val=4
1144
-
res=-9223372036854775808
1145
-
Binary:
1146
-
val=0000000000000000000000000000000000000000000000000000000000000100
1147
-
res=1000000000000000000000000000000000000000000000000000000000000000
1148
-
NOTE: sign bits get shifted out
1149
-

1150
-
Expression: 0 = 4 << 62
1151
-
Decimal:
1152
-
val=4
1153
-
res=0
1154
-
Binary:
1155
-
val=0000000000000000000000000000000000000000000000000000000000000100
1156
-
res=0000000000000000000000000000000000000000000000000000000000000000
1157
-
NOTE: bits shift out left side
1158
-

1159
-

1160
-
--- BIT SHIFT LEFT ON NEGATIVE INTEGERS ---
1161
-
Expression: -8 = -4 << 1
1162
-
Decimal:
1163
-
val=-4
1164
-
res=-8
1165
-
Binary:
1166
-
val=1111111111111111111111111111111111111111111111111111111111111100
1167
-
res=1111111111111111111111111111111111111111111111111111111111111000
1168
-
NOTE: zeros fill in right side
1169
-

1170
-
Expression: -9223372036854775808 = -4 << 61
1171
-
Decimal:
1172
-
val=-4
1173
-
res=-9223372036854775808
1174
-
Binary:
1175
-
val=1111111111111111111111111111111111111111111111111111111111111100
1176
-
res=1000000000000000000000000000000000000000000000000000000000000000
1177
-

1178
-
Expression: 0 = -4 << 62
1179
-
Decimal:
1180
-
val=-4
1181
-
res=0
1182
-
Binary:
1183
-
val=1111111111111111111111111111111111111111111111111111111111111100
1184
-
res=0000000000000000000000000000000000000000000000000000000000000000
1185
-
NOTE: bits shift out left side, including sign bit
1186
-
]]>
1187
-
</screen>
1188
-
</example>
1189
-
</para>
1190
-
<warning>
1191
-
<para>
1192
-
Shifting integers by values greater than or equal to the system long
1193
-
integer width results in undefined behavior. In other words, don't shift
1194
-
more than 31 bits on a 32-bit system, and don't shift more than 63 bits on
1195
-
a 64-bit system.
1196
-
</para>
1197
-
<para>
1198
-
Use functions from the <link linkend="book.gmp">gmp</link> extension for
1199
-
bitwise manipulation on numbers beyond <literal>PHP_INT_MAX</literal>.
1200
-
</para>
1201
-
</warning>
1202
-
<para>
1203
-
See also
1204
-
<function>pack</function>,
1205
-
<function>unpack</function>,
1206
-
<function>gmp_and</function>,
1207
-
<function>gmp_or</function>,
1208
-
<function>gmp_xor</function>,
1209
-
<function>gmp_testbit</function>,
1210
-
<function>gmp_clrbit</function>
1211
-
</para>
1212
-
</sect1>
1213
-

1214
-
<sect1 xml:id="language.operators.comparison">
1215
-
<title>Comparison Operators</title>
1216
-
<simpara>
1217
-
Comparison operators, as their name implies, allow you to compare
1218
-
two values. You may also be interested in viewing
1219
-
<link linkend="types.comparisons">the type comparison tables</link>,
1220
-
as they show examples of various type related comparisons.
1221
-
</simpara>
1222
-
<table>
1223
-
<title>Comparison Operators</title>
1224
-
<tgroup cols="3">
1225
-
<thead>
1226
-
<row>
1227
-
<entry>Example</entry>
1228
-
<entry>Name</entry>
1229
-
<entry>Result</entry>
1230
-
</row>
1231
-
</thead>
1232
-
<tbody>
1233
-
<row>
1234
-
<entry>$a == $b</entry>
1235
-
<entry>Equal</entry>
1236
-
<entry>&true; if <varname>$a</varname> is equal to <varname>$b</varname> after type juggling.</entry>
1237
-
</row>
1238
-
<row>
1239
-
<entry>$a === $b</entry>
1240
-
<entry>Identical</entry>
1241
-
<entry>
1242
-
&true; if <varname>$a</varname> is equal to <varname>$b</varname>, and they are of the same
1243
-
type.
1244
-
</entry>
1245
-
</row>
1246
-
<row>
1247
-
<entry>$a != $b</entry>
1248
-
<entry>Not equal</entry>
1249
-
<entry>&true; if <varname>$a</varname> is not equal to <varname>$b</varname> after type juggling.</entry>
1250
-
</row>
1251
-
<row>
1252
-
<entry>$a &lt;&gt; $b</entry>
1253
-
<entry>Not equal</entry>
1254
-
<entry>&true; if <varname>$a</varname> is not equal to <varname>$b</varname> after type juggling.</entry>
1255
-
</row>
1256
-
<row>
1257
-
<entry>$a !== $b</entry>
1258
-
<entry>Not identical</entry>
1259
-
<entry>
1260
-
&true; if <varname>$a</varname> is not equal to <varname>$b</varname>, or they are not of the same
1261
-
type.
1262
-
</entry>
1263
-
</row>
1264
-
<row>
1265
-
<entry>$a &lt; $b</entry>
1266
-
<entry>Less than</entry>
1267
-
<entry>&true; if <varname>$a</varname> is strictly less than <varname>$b</varname>.</entry>
1268
-
</row>
1269
-
<row>
1270
-
<entry>$a &gt; $b</entry>
1271
-
<entry>Greater than</entry>
1272
-
<entry>&true; if <varname>$a</varname> is strictly greater than <varname>$b</varname>.</entry>
1273
-
</row>
1274
-
<row>
1275
-
<entry>$a &lt;= $b</entry>
1276
-
<entry>Less than or equal to </entry>
1277
-
<entry>&true; if <varname>$a</varname> is less than or equal to <varname>$b</varname>.</entry>
1278
-
</row>
1279
-
<row>
1280
-
<entry>$a &gt;= $b</entry>
1281
-
<entry>Greater than or equal to </entry>
1282
-
<entry>&true; if <varname>$a</varname> is greater than or equal to <varname>$b</varname>.</entry>
1283
-
</row>
1284
-
</tbody>
1285
-
</tgroup>
1286
-
</table>
1287
-
<para>
1288
-
If you compare a number with a string or the comparison involves numerical
1289
-
strings, then each string is
1290
-
<link linkend="language.types.string.conversion">converted to a number</link>
1291
-
and the comparison performed numerically. These rules also apply to the
1292
-
<link linkend="control-structures.switch">switch</link> statement. The
1293
-
type conversion does not take place when the comparison is === or !== as
1294
-
this involves comparing the type as well as the value.
1295
-
<informalexample>
1296
-
<programlisting role="php">
1297
-
<![CDATA[
1298
-
<?php
1299
-
var_dump(0 == "a"); // 0 == 0 -> true
1300
-
var_dump("1" == "01"); // 1 == 1 -> true
1301
-
var_dump("10" == "1e1"); // 10 == 10 -> true
1302
-
var_dump(100 == "1e2"); // 100 == 100 -> true
1303
-

1304
-
switch ("a") {
1305
-
case 0:
1306
-
echo "0";
1307
-
break;
1308
-
case "a": // never reached because "a" is already matched with 0
1309
-
echo "a";
1310
-
break;
1311
-
}
1312
-
?>
1313
-
]]>
1314
-
</programlisting>
1315
-
</informalexample>
1316
-
</para>
1317
-

1318
-
<para>
1319
-
For various types, comparison is done according to the following
1320
-
table (in order).
1321
-
</para>
1322
-
<table xml:id="language.operators.comparison.types">
1323
-
<title>Comparison with Various Types</title>
1324
-
<tgroup cols="3">
1325
-
<thead>
1326
-
<row>
1327
-
<entry>Type of Operand 1</entry>
1328
-
<entry>Type of Operand 2</entry>
1329
-
<entry>Result</entry>
1330
-
</row>
1331
-
</thead>
1332
-
<tbody>
1333
-
<row>
1334
-
<entry><type>null</type> or <type>string</type></entry>
1335
-
<entry><type>string</type></entry>
1336
-
<entry>Convert &null; to "", numerical or lexical comparison</entry>
1337
-
</row>
1338
-
<row>
1339
-
<entry><type>bool</type> or <type>null</type></entry>
1340
-
<entry>anything</entry>
1341
-
<entry>Convert both sides to <type>bool</type>, &false; &lt; &true;</entry>
1342
-
</row>
1343
-
<row>
1344
-
<entry><type>object</type></entry>
1345
-
<entry><type>object</type></entry>
1346
-
<entry>Built-in classes can define its own comparison, different classes
1347
-
are uncomparable, same class - compare properties the same way as
1348
-
arrays (PHP 4), PHP 5 has its own <link
1349
-
linkend="language.oop5.object-comparison">explanation</link>
1350
-
</entry>
1351
-
</row>
1352
-
<row>
1353
-
<entry><type>string</type>, <type>resource</type> or <type>number</type></entry>
1354
-
<entry><type>string</type>, <type>resource</type> or <type>number</type></entry>
1355
-
<entry>Translate strings and resources to numbers, usual math</entry>
1356
-
</row>
1357
-
<row>
1358
-
<entry><type>array</type></entry>
1359
-
<entry><type>array</type></entry>
1360
-
<entry>Array with fewer members is smaller, if key from operand 1 is not
1361
-
found in operand 2 then arrays are uncomparable, otherwise - compare
1362
-
value by value (see following example)</entry>
1363
-
</row>
1364
-
<row>
1365
-
<entry><type>object</type></entry>
1366
-
<entry>anything</entry>
1367
-
<entry><type>object</type> is always greater</entry>
1368
-
</row>
1369
-
<row>
1370
-
<entry><type>array</type></entry>
1371
-
<entry>anything</entry>
1372
-
<entry><type>array</type> is always greater</entry>
1373
-
</row>
1374
-
</tbody>
1375
-
</tgroup>
1376
-
</table>
1377
-

1378
-
<para>
1379
-
<example>
1380
-
<title>Boolean/null comparison</title>
1381
-
<programlisting role="php">
1382
-
<![CDATA[
1383
-
<?php
1384
-
// Bool and null are compared as bool always
1385
-
var_dump(1 == TRUE); // TRUE - same as (bool)1 == TRUE
1386
-
var_dump(0 == FALSE); // TRUE - same as (bool)0 == FALSE
1387
-
var_dump(100 < TRUE); // FALSE - same as (bool)100 < TRUE
1388
-
var_dump(-10 < FALSE);// FALSE - same as (bool)-10 < FALSE
1389
-
var_dump(min(-100, -10, NULL, 10, 100)); // NULL - (bool)NULL < (bool)-100 is FALSE < TRUE
1390
-
?>
1391
-
]]>
1392
-
</programlisting>
1393
-
</example>
1394
-
</para>
1395
-

1396
-

1397
-
<para>
1398
-
<example>
1399
-
<title>Transcription of standard array comparison</title>
1400
-
<programlisting role="php">
1401
-
<![CDATA[
1402
-
<?php
1403
-
// Arrays are compared like this with standard comparison operators
1404
-
function standard_array_compare($op1, $op2)
1405
-
{
1406
-
if (count($op1) < count($op2)) {
1407
-
return -1; // $op1 < $op2
1408
-
} elseif (count($op1) > count($op2)) {
1409
-
return 1; // $op1 > $op2
1410
-
}
1411
-
foreach ($op1 as $key => $val) {
1412
-
if (!array_key_exists($key, $op2)) {
1413
-
return null; // uncomparable
1414
-
} elseif ($val < $op2[$key]) {
1415
-
return -1;
1416
-
} elseif ($val > $op2[$key]) {
1417
-
return 1;
1418
-
}
1419
-
}
1420
-
return 0; // $op1 == $op2
1421
-
}
1422
-
?>
1423
-
]]>
1424
-
</programlisting>
1425
-
</example>
1426
-
</para>
1427
-

1428
-
<para>
1429
-
See also <function>strcasecmp</function>,
1430
-
<function>strcmp</function>,
1431
-
<link linkend="language.operators.array">Array operators</link>,
1432
-
and the manual section on
1433
-
<link linkend="language.types">Types</link>.
1434
-
</para>
1435
-

1436
-
<warning>
1437
-
<title>Comparison of floating point numbers</title>
1438
-

1439
-
<para>
1440
-
Because of the way <type>float</type>s are represented internally, you
1441
-
should not test two <type>float</type>s for equality.
1442
-
</para>
1443
-

1444
-
<para>
1445
-
See the documentation for <type>float</type> for more information.
1446
-
</para>
1447
-
</warning>
1448
-

1449
-
<sect2 xml:id="language.operators.comparison.ternary">
1450
-
<title>Ternary Operator</title>
1451
-
<para>
1452
-
Another conditional operator is the "?:" (or ternary) operator.
1453
-
<example>
1454
-
<title>Assigning a default value</title>
1455
-
<programlisting role="php">
1456
-
<![CDATA[
1457
-
<?php
1458
-
// Example usage for: Ternary Operator
1459
-
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
1460
-

1461
-
// The above is identical to this if/else statement
1462
-
if (empty($_POST['action'])) {
1463
-
$action = 'default';
1464
-
} else {
1465
-
$action = $_POST['action'];
1466
-
}
1467
-

1468
-
?>
1469
-
]]>
1470
-
</programlisting>
1471
-
</example>
1472
-
The expression <literal>(expr1) ? (expr2) : (expr3)</literal>
1473
-
evaluates to <replaceable>expr2</replaceable> if
1474
-
<replaceable>expr1</replaceable> evaluates to &true;, and
1475
-
<replaceable>expr3</replaceable> if
1476
-
<replaceable>expr1</replaceable> evaluates to &false;.
1477
-
</para>
1478
-
<para>
1479
-
Since PHP 5.3, it is possible to leave out the middle part of the ternary
1480
-
operator. Expression <literal>expr1 ?: expr3</literal> returns
1481
-
<replaceable>expr1</replaceable> if <replaceable>expr1</replaceable>
1482
-
evaluates to &true;, and <replaceable>expr3</replaceable> otherwise.
1483
-
</para>
1484
-
<note>
1485
-
<simpara>
1486
-
Please note that the ternary operator is an expression, and that it
1487
-
doesn't evaluate to a variable, but to the result of an expression. This
1488
-
is important to know if you want to return a variable by reference.
1489
-
The statement <literal>return $var == 42 ? $a : $b;</literal> in a
1490
-
return-by-reference function will therefore not work and a warning is
1491
-
issued in later PHP versions.
1492
-
</simpara>
1493
-
</note>
1494
-
<note>
1495
-
<para>
1496
-
It is recommended that you avoid "stacking" ternary expressions. PHP's
1497
-
behaviour when using more than one ternary operator within a single
1498
-
statement is non-obvious:
1499
-
<example>
1500
-
<title>Non-obvious Ternary Behaviour</title>
1501
-
<programlisting role="php">
1502
-
<![CDATA[
1503
-
<?php
1504
-
// on first glance, the following appears to output 'true'
1505
-
echo (true?'true':false?'t':'f');
1506
-

1507
-
// however, the actual output of the above is 't'
1508
-
// this is because ternary expressions are evaluated from left to right
1509
-

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

1513
-
// here, you can see that the first expression is evaluated to 'true', which
1514
-
// in turn evaluates to (bool)true, thus returning the true branch of the
1515
-
// second ternary expression.
1516
-
?>
1517
-
]]>
1518
-
</programlisting>
1519
-
</example>
1520
-
</para>
1521
-
</note>
1522
-
</sect2>
1523
-

1524
-
</sect1>
1525
-

1526
-
<sect1 xml:id="language.operators.errorcontrol">
1527
-
<title>Error Control Operators</title>
1528
-
<simpara>
1529
-
PHP supports one error control operator: the at sign (@). When
1530
-
prepended to an expression in PHP, any error messages that might
1531
-
be generated by that expression will be ignored.
1532
-
</simpara>
1533
-
<simpara>
1534
-
If you have set a custom error handler function with
1535
-
<function>set_error_handler</function> then it will still get
1536
-
called, but this custom error handler can (and should) call <function>error_reporting</function>
1537
-
which will return 0 when the call that triggered the error was preceded by an @.
1538
-
</simpara>
1539
-
<simpara>
1540
-
If the <link linkend="ini.track-errors"><option>track_errors</option></link>
1541
-
feature is enabled, any error message generated by the expression
1542
-
will be saved in the variable
1543
-
<varname>$php_errormsg</varname>.
1544
-
This variable will be overwritten on each error, so check early if you
1545
-
want to use it.
1546
-
</simpara>
1547
-
<para>
1548
-
<informalexample>
1549
-
<programlisting role="php">
1550
-
<![CDATA[
1551
-
<?php
1552
-
/* Intentional file error */
1553
-
$my_file = @file ('non_existent_file') or
1554
-
die ("Failed opening file: error was '$php_errormsg'");
1555
-

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

1560
-
?>
1561
-
]]>
1562
-
</programlisting>
1563
-
</informalexample>
1564
-
</para>
1565
-
<note>
1566
-
<simpara>
1567
-
The @-operator works only on
1568
-
<link linkend="language.expressions">expressions</link>. A simple rule
1569
-
of thumb is: if you can take the value of something, you can prepend
1570
-
the @ operator to it. For instance, you can prepend it to variables,
1571
-
function and <function>include</function> calls, constants, and
1572
-
so forth. You cannot prepend it to function or class definitions,
1573
-
or conditional structures such as <literal>if</literal> and
1574
-
&foreach;, and so forth.
1575
-
</simpara>
1576
-
</note>
1577
-
<simpara>
1578
-
See also <function>error_reporting</function> and the manual section for
1579
-
<link linkend="ref.errorfunc">Error Handling and Logging functions</link>.
1580
-
</simpara>
1581
-
<warning>
1582
-
<para>
1583
-
Currently the "@" error-control operator prefix will even disable
1584
-
error reporting for critical errors that will terminate script
1585
-
execution. Among other things, this means that if you use "@" to
1586
-
suppress errors from a certain function and either it isn't
1587
-
available or has been mistyped, the script will die right there
1588
-
with no indication as to why.
1589
-
</para>
1590
-
</warning>
1591
-
</sect1>
1592
-

1593
-
<sect1 xml:id="language.operators.execution">
1594
-
<title>Execution Operators</title>
1595
-
<para>
1596
-
PHP supports one execution operator: backticks (``). Note that
1597
-
these are not single-quotes! PHP will attempt to execute the
1598
-
contents of the backticks as a shell command; the output will be
1599
-
returned (i.e., it won't simply be dumped to output; it can be
1600
-
assigned to a variable). Use of the backtick operator is identical
1601
-
to <function>shell_exec</function>.
1602
-
<informalexample>
1603
-
<programlisting role="php">
1604
-
<![CDATA[
1605
-
<?php
1606
-
$output = `ls -al`;
1607
-
echo "<pre>$output</pre>";
1608
-
?>
1609
-
]]>
1610
-
</programlisting>
1611
-
</informalexample>
1612
-
</para>
1613
-
<note>
1614
-
<para>
1615
-
The backtick operator is disabled when &safemode; is enabled
1616
-
or <function>shell_exec</function> is disabled.
1617
-
</para>
1618
-
</note>
1619
-
<note>
1620
-
<para>
1621
-
Unlike some other languages, backticks cannot be used within
1622
-
double-quoted strings.
1623
-
</para>
1624
-
</note>
1625
-
<para>
1626
-
See also the manual section on <link linkend="ref.exec">Program
1627
-
Execution functions</link>, <function>popen</function>
1628
-
<function>proc_open</function>, and
1629
-
<link linkend="features.commandline">Using PHP from the
1630
-
commandline</link>.
1631
-
</para>
1632
-
</sect1>
1633
-

1634
-
<sect1 xml:id="language.operators.increment">
1635
-
<title>Incrementing/Decrementing Operators</title>
1636
-
<para>
1637
-
PHP supports C-style pre- and post-increment and decrement
1638
-
operators.
1639
-
</para>
1640
-
<note>
1641
-
<simpara>
1642
-
The increment/decrement operators only affect numbers and strings.
1643
-
Arrays, objects and resources are not affected.
1644
-
Decrementing &null; values has no effect too, but incrementing them
1645
-
results in <literal>1</literal>.
1646
-
</simpara>
1647
-
</note>
1648
-
<table>
1649
-
<title>Increment/decrement Operators</title>
1650
-
<tgroup cols="3">
1651
-
<thead>
1652
-
<row>
1653
-
<entry>Example</entry>
1654
-
<entry>Name</entry>
1655
-
<entry>Effect</entry>
1656
-
</row>
1657
-
</thead>
1658
-
<tbody>
1659
-
<row>
1660
-
<entry>++$a</entry>
1661
-
<entry>Pre-increment</entry>
1662
-
<entry>Increments <varname>$a</varname> by one, then returns <varname>$a</varname>.</entry>
1663
-
</row>
1664
-
<row>
1665
-
<entry>$a++</entry>
1666
-
<entry>Post-increment</entry>
1667
-
<entry>Returns <varname>$a</varname>, then increments <varname>$a</varname> by one.</entry>
1668
-
</row>
1669
-
<row>
1670
-
<entry>--$a</entry>
1671
-
<entry>Pre-decrement</entry>
1672
-
<entry>Decrements <varname>$a</varname> by one, then returns <varname>$a</varname>.</entry>
1673
-
</row>
1674
-
<row>
1675
-
<entry>$a--</entry>
1676
-
<entry>Post-decrement</entry>
1677
-
<entry>Returns <varname>$a</varname>, then decrements <varname>$a</varname> by one.</entry>
1678
-
</row>
1679
-
</tbody>
1680
-
</tgroup>
1681
-
</table>
1682
-
<para>
1683
-
Here's a simple example script:
1684
-
<informalexample>
1685
-
<programlisting role="php">
1686
-
<![CDATA[
1687
-
<?php
1688
-
echo "<h3>Postincrement</h3>";
1689
-
$a = 5;
1690
-
echo "Should be 5: " . $a++ . "<br />\n";
1691
-
echo "Should be 6: " . $a . "<br />\n";
1692
-

1693
-
echo "<h3>Preincrement</h3>";
1694
-
$a = 5;
1695
-
echo "Should be 6: " . ++$a . "<br />\n";
1696
-
echo "Should be 6: " . $a . "<br />\n";
1697
-

1698
-
echo "<h3>Postdecrement</h3>";
1699
-
$a = 5;
1700
-
echo "Should be 5: " . $a-- . "<br />\n";
1701
-
echo "Should be 4: " . $a . "<br />\n";
1702
-

1703
-
echo "<h3>Predecrement</h3>";
1704
-
$a = 5;
1705
-
echo "Should be 4: " . --$a . "<br />\n";
1706
-
echo "Should be 4: " . $a . "<br />\n";
1707
-
?>
1708
-
]]>
1709
-
</programlisting>
1710
-
</informalexample>
1711
-
</para>
1712
-
<para>
1713
-
PHP follows Perl's convention when dealing with arithmetic operations
1714
-
on character variables and not C's. For example, in PHP and Perl
1715
-
<literal>$a = 'Z'; $a++;</literal> turns <literal>$a</literal> into <literal>'AA'</literal>, while in C
1716
-
<literal>a = 'Z'; a++;</literal> turns <literal>a</literal> into <literal>'['</literal>
1717
-
(ASCII value of <literal>'Z'</literal> is 90, ASCII value of <literal>'['</literal> is 91).
1718
-
Note that character variables can be incremented but not decremented and
1719
-
even so only plain ASCII alphabets and digits (a-z, A-Z and 0-9) are supported.
1720
-
Incrementing/decrementing other character variables has no effect, the
1721
-
original string is unchanged.
1722
-
<example>
1723
-
<title>Arithmetic Operations on Character Variables</title>
1724
-
<programlisting role="php">
1725
-
<![CDATA[
1726
-
<?php
1727
-
echo '== Alphabets ==' . PHP_EOL;
1728
-
$s = 'W';
1729
-
for ($n=0; $n<6; $n++) {
1730
-
echo ++$s . PHP_EOL;
1731
-
}
1732
-
// Digit characters behave differently
1733
-
echo '== Digits ==' . PHP_EOL;
1734
-
$d = 'A8';
1735
-
for ($n=0; $n<6; $n++) {
1736
-
echo ++$d . PHP_EOL;
1737
-
}
1738
-
$d = 'A08';
1739
-
for ($n=0; $n<6; $n++) {
1740
-
echo ++$d . PHP_EOL;
1741
-
}
1742
-
?>
1743
-
]]>
1744
-
</programlisting>
1745
-
&example.outputs;
1746
-
<screen>
1747
-
<![CDATA[
1748
-
== Characters ==
1749
-
X
1750
-
Y
1751
-
Z
1752
-
AA
1753
-
AB
1754
-
AC
1755
-
== Digits ==
1756
-
A9
1757
-
B0
1758
-
B1
1759
-
B2
1760
-
B3
1761
-
B4
1762
-
A09
1763
-
A10
1764
-
A11
1765
-
A12
1766
-
A13
1767
-
A14
1768
-
]]>
1769
-
</screen>
1770
-
</example>
1771
-
</para>
1772
-
<para>
1773
-
Incrementing or decrementing booleans has no effect.
1774
-
</para>
1775
-
</sect1>
1776
-

1777
-
<sect1 xml:id="language.operators.logical">
1778
-
<title>Logical Operators</title>
1779
-

1780
-
<table>
1781
-
<title>Logical Operators</title>
1782
-
<tgroup cols="3">
1783
-
<thead>
1784
-
<row>
1785
-
<entry>Example</entry>
1786
-
<entry>Name</entry>
1787
-
<entry>Result</entry>
1788
-
</row>
1789
-
</thead>
1790
-
<tbody>
1791
-
<row>
1792
-
<entry>$a and $b</entry>
1793
-
<entry>And</entry>
1794
-
<entry>&true; if both <varname>$a</varname> and <varname>$b</varname> are &true;.</entry>
1795
-
</row>
1796
-
<row>
1797
-
<entry>$a or $b</entry>
1798
-
<entry>Or</entry>
1799
-
<entry>&true; if either <varname>$a</varname> or <varname>$b</varname> is &true;.</entry>
1800
-
</row>
1801
-
<row>
1802
-
<entry>$a xor $b</entry>
1803
-
<entry>Xor</entry>
1804
-
<entry>&true; if either <varname>$a</varname> or <varname>$b</varname> is &true;, but not both.</entry>
1805
-
</row>
1806
-
<row>
1807
-
<entry>! $a</entry>
1808
-
<entry>Not</entry>
1809
-
<entry>&true; if <varname>$a</varname> is not &true;.</entry>
1810
-
</row>
1811
-
<row>
1812
-
<entry>$a &amp;&amp; $b</entry>
1813
-
<entry>And</entry>
1814
-
<entry>&true; if both <varname>$a</varname> and <varname>$b</varname> are &true;.</entry>
1815
-
</row>
1816
-
<row>
1817
-
<entry>$a || $b</entry>
1818
-
<entry>Or</entry>
1819
-
<entry>&true; if either <varname>$a</varname> or <varname>$b</varname> is &true;.</entry>
1820
-
</row>
1821
-
</tbody>
1822
-
</tgroup>
1823
-
</table>
1824
-
<simpara>
1825
-
The reason for the two different variations of "and" and "or"
1826
-
operators is that they operate at different precedences. (See
1827
-
<link linkend="language.operators.precedence">Operator
1828
-
Precedence</link>.)
1829
-
</simpara>
1830
-
<example>
1831
-
<title>Logical operators illustrated</title>
1832
-
<programlisting role="php">
1833
-
<![CDATA[
1834
-
<?php
1835
-

1836
-
// --------------------
1837
-
// foo() will never get called as those operators are short-circuit
1838
-

1839
-
$a = (false && foo());
1840
-
$b = (true || foo());
1841
-
$c = (false and foo());
1842
-
$d = (true or foo());
1843
-

1844
-
// --------------------
1845
-
// "||" has a greater precedence than "or"
1846
-

1847
-
// The result of the expression (false || true) is assigned to $e
1848
-
// Acts like: ($e = (false || true))
1849
-
$e = false || true;
1850
-

1851
-
// The constant false is assigned to $f and then true is ignored
1852
-
// Acts like: (($f = false) or true)
1853
-
$f = false or true;
1854
-

1855
-
var_dump($e, $f);
1856
-

1857
-
// --------------------
1858
-
// "&&" has a greater precedence than "and"
1859
-

1860
-
// The result of the expression (true && false) is assigned to $g
1861
-
// Acts like: ($g = (true && false))
1862
-
$g = true && false;
1863
-

1864
-
// The constant true is assigned to $h and then false is ignored
1865
-
// Acts like: (($h = true) and false)
1866
-
$h = true and false;
1867
-

1868
-
var_dump($g, $h);
1869
-
?>
1870
-
]]>
1871
-
</programlisting>
1872
-
&example.outputs.similar;
1873
-
<screen>
1874
-
<![CDATA[
1875
-
bool(true)
1876
-
bool(false)
1877
-
bool(false)
1878
-
bool(true)
1879
-
]]>
1880
-
</screen>
1881
-
</example>
1882
-
</sect1>
1883
-

1884
-
<sect1 xml:id="language.operators.string">
1885
-
<title>String Operators</title>
1886
-
<simpara>
1887
-
There are two <type>string</type> operators. The first is the
1888
-
concatenation operator ('.'), which returns the concatenation of its
1889
-
right and left arguments. The second is the concatenating assignment
1890
-
operator ('<literal>.=</literal>'), which appends the argument on the right side to
1891
-
the argument on the left side. Please read <link
1892
-
linkend="language.operators.assignment">Assignment
1893
-
Operators</link> for more information.
1894
-
</simpara>
1895
-

1896
-
<para>
1897
-
<informalexample>
1898
-
<programlisting role="php">
1899
-
<![CDATA[
1900
-
<?php
1901
-
$a = "Hello ";
1902
-
$b = $a . "World!"; // now $b contains "Hello World!"
1903
-

1904
-
$a = "Hello ";
1905
-
$a .= "World!"; // now $a contains "Hello World!"
1906
-
?>
1907
-
]]>
1908
-
</programlisting>
1909
-
</informalexample>
1910
-
</para>
1911
-
<para>
1912
-
See also the manual sections on the
1913
-
<link linkend="language.types.string">String type</link> and
1914
-
<link linkend="ref.strings">String functions</link>.
1915
-
</para>
1916
-
</sect1>
1917
-

1918
-
<sect1 xml:id="language.operators.array">
1919
-
<title>Array Operators</title>
1920
-
<table>
1921
-
<title>Array Operators</title>
1922
-
<tgroup cols="3">
1923
-
<thead>
1924
-
<row>
1925
-
<entry>Example</entry>
1926
-
<entry>Name</entry>
1927
-
<entry>Result</entry>
1928
-
</row>
1929
-
</thead>
1930
-
<tbody>
1931
-
<row>
1932
-
<entry>$a + $b</entry>
1933
-
<entry>Union</entry>
1934
-
<entry>Union of <varname>$a</varname> and <varname>$b</varname>.</entry>
1935
-
</row>
1936
-
<row>
1937
-
<entry>$a == $b</entry>
1938
-
<entry>Equality</entry>
1939
-
<entry>&true; if <varname>$a</varname> and <varname>$b</varname> have the same key/value pairs.</entry>
1940
-
</row>
1941
-
<row>
1942
-
<entry>$a === $b</entry>
1943
-
<entry>Identity</entry>
1944
-
<entry>&true; if <varname>$a</varname> and <varname>$b</varname> have the same key/value pairs in the same
1945
-
order and of the same types.</entry>
1946
-
</row>
1947
-
<row>
1948
-
<entry>$a != $b</entry>
1949
-
<entry>Inequality</entry>
1950
-
<entry>&true; if <varname>$a</varname> is not equal to <varname>$b</varname>.</entry>
1951
-
</row>
1952
-
<row>
1953
-
<entry>$a &lt;&gt; $b</entry>
1954
-
<entry>Inequality</entry>
1955
-
<entry>&true; if <varname>$a</varname> is not equal to <varname>$b</varname>.</entry>
1956
-
</row>
1957
-
<row>
1958
-
<entry>$a !== $b</entry>
1959
-
<entry>Non-identity</entry>
1960
-
<entry>&true; if <varname>$a</varname> is not identical to <varname>$b</varname>.</entry>
1961
-
</row>
1962
-
</tbody>
1963
-
</tgroup>
1964
-
</table>
1965
-
<para>
1966
-
The <literal>+</literal> operator returns the right-hand array appended
1967
-
to the left-hand array; for keys that exist in both arrays, the elements
1968
-
from the left-hand array will be used, and the matching elements from the
1969
-
right-hand array will be ignored.
1970
-
</para>
1971
-
<para>
1972
-
<informalexample>
1973
-
<programlisting role="php">
1974
-
<![CDATA[
1975
-
<?php
1976
-
$a = array("a" => "apple", "b" => "banana");
1977
-
$b = array("a" => "pear", "b" => "strawberry", "c" => "cherry");
1978
-

1979
-
$c = $a + $b; // Union of $a and $b
1980
-
echo "Union of \$a and \$b: \n";
1981
-
var_dump($c);
1982
-

1983
-
$c = $b + $a; // Union of $b and $a
1984
-
echo "Union of \$b and \$a: \n";
1985
-
var_dump($c);
1986
-
?>
1987
-
]]>
1988
-
</programlisting>
1989
-
</informalexample>
1990
-
When executed, this script will print the following:
1991
-
<screen role="php">
1992
-
<![CDATA[
1993
-
Union of $a and $b:
1994
-
array(3) {
1995
-
["a"]=>
1996
-
string(5) "apple"
1997
-
["b"]=>
1998
-
string(6) "banana"
1999
-
["c"]=>
2000
-
string(6) "cherry"
2001
-
}
2002
-
Union of $b and $a:
2003
-
array(3) {
2004
-
["a"]=>
2005
-
string(4) "pear"
2006
-
["b"]=>
2007
-
string(10) "strawberry"
2008
-
["c"]=>
2009
-
string(6) "cherry"
2010
-
}
2011
-
]]>
2012
-
</screen>
2013
-
</para>
2014
-
<para>
2015
-
Elements of arrays are equal for the comparison if they have the
2016
-
same key and value.
2017
-
</para>
2018
-
<para>
2019
-
<example>
2020
-
<title>Comparing arrays</title>
2021
-
<programlisting role="php">
2022
-
<![CDATA[
2023
-
<?php
2024
-
$a = array("apple", "banana");
2025
-
$b = array(1 => "banana", "0" => "apple");
2026
-

2027
-
var_dump($a == $b); // bool(true)
2028
-
var_dump($a === $b); // bool(false)
2029
-
?>
2030
-
]]>
2031
-
</programlisting>
2032
-
</example>
2033
-
</para>
2034
-
<para>
2035
-
See also the manual sections on the
2036
-
<link linkend="language.types.array">Array type</link> and
2037
-
<link linkend="ref.array">Array functions</link>.
2038
-
</para>
2039
-
</sect1>
2040
-
<sect1 xml:id="language.operators.type">
2041
-
<title>Type Operators</title>
2042
-
<para>
2043
-
<literal>instanceof</literal> is used to determine whether a PHP variable
2044
-
is an instantiated object of a certain
2045
-
<link linkend="language.oop5.basic.class">class</link>:
2046
-
<example>
2047
-
<title>Using <literal>instanceof</literal> with classes</title>
2048
-
<programlisting role="php">
2049
-
<![CDATA[
2050
-
<?php
2051
-
class MyClass
2052
-
{
2053
-
}
2054
-

2055
-
class NotMyClass
2056
-
{
2057
-
}
2058
-
$a = new MyClass;
2059
-

2060
-
var_dump($a instanceof MyClass);
2061
-
var_dump($a instanceof NotMyClass);
2062
-
?>
2063
-
]]>
2064
-
</programlisting>
2065
-
&example.outputs;
2066
-
<screen>
2067
-
<![CDATA[
2068
-
bool(true)
2069
-
bool(false)
2070
-
]]>
2071
-
</screen>
2072
-
</example>
2073
-
</para>
2074
-
<para>
2075
-
<literal>instanceof</literal> can also be used to determine whether a variable
2076
-
is an instantiated object of a class that inherits from a parent class:
2077
-
<example>
2078
-
<title>Using <literal>instanceof</literal> with inherited classes</title>
2079
-
<programlisting role="php">
2080
-
<![CDATA[
2081
-
<?php
2082
-
class ParentClass
2083
-
{
2084
-
}
2085
-

2086
-
class MyClass extends ParentClass
2087
-
{
2088
-
}
2089
-

2090
-
$a = new MyClass;
2091
-

2092
-
var_dump($a instanceof MyClass);
2093
-
var_dump($a instanceof ParentClass);
2094
-
?>
2095
-
]]>
2096
-
</programlisting>
2097
-
&example.outputs;
2098
-
<screen>
2099
-
<![CDATA[
2100
-
bool(true)
2101
-
bool(true)
2102
-
]]>
2103
-
</screen>
2104
-
</example>
2105
-
</para>
2106
-
<para>
2107
-
To check if an object is <emphasis>not</emphasis> an instanceof a class, the
2108
-
<link linkend="language.operators.logical">logical <literal>not</literal>
2109
-
operator</link> can be used.
2110
-
<example>
2111
-
<title>Using <literal>instanceof</literal> to check if object is <emphasis>not</emphasis> an
2112
-
instanceof a class</title>
2113
-
<programlisting role="php">
2114
-
<![CDATA[
2115
-
<?php
2116
-
class MyClass
2117
-
{
2118
-
}
2119
-

2120
-
$a = new MyClass;
2121
-
var_dump(!($a instanceof stdClass));
2122
-
?>
2123
-
]]>
2124
-
</programlisting>
2125
-
&example.outputs;
2126
-
<screen>
2127
-
<![CDATA[
2128
-
bool(true)
2129
-
]]>
2130
-
</screen>
2131
-
</example>
2132
-
</para>
2133
-
<para>
2134
-
Lastly, <literal>instanceof</literal> can also be used to determine whether
2135
-
a variable is an instantiated object of a class that implements an
2136
-
<link linkend="language.oop5.interfaces">interface</link>:
2137
-
<example>
2138
-
<title>Using <literal>instanceof</literal> for class</title>
2139
-
<programlisting role="php">
2140
-
<![CDATA[
2141
-
<?php
2142
-
interface MyInterface
2143
-
{
2144
-
}
2145
-

2146
-
class MyClass implements MyInterface
2147
-
{
2148
-
}
2149
-

2150
-
$a = new MyClass;
2151
-

2152
-
var_dump($a instanceof MyClass);
2153
-
var_dump($a instanceof MyInterface);
2154
-
?>
2155
-
]]>
2156
-
</programlisting>
2157
-
&example.outputs;
2158
-
<screen>
2159
-
<![CDATA[
2160
-
bool(true)
2161
-
bool(true)
2162
-
]]>
2163
-
</screen>
2164
-
</example>
2165
-
</para>
2166
-
<para>
2167
-
Although <literal>instanceof</literal> is usually used with a literal classname,
2168
-
it can also be used with another object or a string variable:
2169
-
<example>
2170
-
<title>Using <literal>instanceof</literal> with other variables</title>
2171
-
<programlisting role="php">
2172
-
<![CDATA[
2173
-
<?php
2174
-
interface MyInterface
2175
-
{
2176
-
}
2177
-

2178
-
class MyClass implements MyInterface
2179
-
{
2180
-
}
2181
-

2182
-
$a = new MyClass;
2183
-
$b = new MyClass;
2184
-
$c = 'MyClass';
2185
-
$d = 'NotMyClass';
2186
-

2187
-
var_dump($a instanceof $b); // $b is an object of class MyClass
2188
-
var_dump($a instanceof $c); // $c is a string 'MyClass'
2189
-
var_dump($a instanceof $d); // $d is a string 'NotMyClass'
2190
-
?>
2191
-
]]>
2192
-
</programlisting>
2193
-
&example.outputs;
2194
-
<screen>
2195
-
<![CDATA[
2196
-
bool(true)
2197
-
bool(true)
2198
-
bool(false)
2199
-
]]>
2200
-
</screen>
2201
-
</example>
2202
-
</para>
2203
-
<para>
2204
-
instanceof does not throw any error if the variable being tested is not
2205
-
an object, it simply returns &false;. Constants, however, are not allowed.
2206
-
<example>
2207
-
<title>Using <literal>instanceof</literal> to test other variables</title>
2208
-
<programlisting role="php">
2209
-
<![CDATA[
2210
-
<?php
2211
-
$a = 1;
2212
-
$b = NULL;
2213
-
$c = imagecreate(5, 5);
2214
-
var_dump($a instanceof stdClass); // $a is an integer
2215
-
var_dump($b instanceof stdClass); // $b is NULL
2216
-
var_dump($c instanceof stdClass); // $c is a resource
2217
-
var_dump(FALSE instanceof stdClass);
2218
-
?>
2219
-
]]>
2220
-
</programlisting>
2221
-
&example.outputs;
2222
-
<screen>
2223
-
<![CDATA[
2224
-
bool(false)
2225
-
bool(false)
2226
-
bool(false)
2227
-
PHP Fatal error: instanceof expects an object instance, constant given
2228
-
]]>
2229
-
</screen>
2230
-
</example>
2231
-
</para>
2232
-
<para>
2233
-
There are a few pitfalls to be aware of. Before PHP version 5.1.0,
2234
-
<literal>instanceof</literal> would call <function>__autoload</function>
2235
-
if the class name did not exist. In addition, if the class was not loaded,
2236
-
a fatal error would occur. This can be worked around by using a dynamic
2237
-
class reference, or a string variable containing the class name:
2238
-
<example>
2239
-
<title>Avoiding classname lookups and fatal errors with <literal>instanceof</literal> in PHP 5.0</title>
2240
-
<programlisting role="php">
2241
-
<![CDATA[
2242
-
<?php
2243
-
$d = 'NotMyClass';
2244
-
var_dump($a instanceof $d); // no fatal error here
2245
-
?>
2246
-
]]>
2247
-
</programlisting>
2248
-
&example.outputs;
2249
-
<screen>
2250
-
<![CDATA[
2251
-
bool(false)
2252
-
]]>
2253
-
</screen>
2254
-
</example>
2255
-
</para>
2256
-
<simpara>
2257
-
The <literal>instanceof</literal> operator was introduced in PHP 5.
2258
-
Before this time <function>is_a</function> was used but
2259
-
<function>is_a</function> has since been deprecated in favor of
2260
-
<literal>instanceof</literal>. Note that as of PHP 5.3.0,
2261
-
<function>is_a</function> is no longer deprecated.
2262
-
</simpara>
2263
-
<para>
2264
-
See also <function>get_class</function> and
2265
-
<function>is_a</function>.
2266
-
</para>
2267
-
</sect1>
2268
-
</chapter>
2269
-

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>
2270
47
<!-- Keep this comment at the end of the file
2271
48
Local variables:
2272
49
mode: sgml
2273
50