mirror of
https://github.com/sigmasternchen/php-doc-en
synced 2025-03-17 01:18:55 +00:00

git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@232426 c90b9560-bf6c-de11-be94-00142212c4b1
1337 lines
37 KiB
XML
1337 lines
37 KiB
XML
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
<!-- $Revision: 1.112 $ -->
|
|
<chapter id="language.operators">
|
|
<title>Operators</title>
|
|
<simpara>
|
|
An operator is something that you feed with one or more values (or
|
|
expressions, in programming jargon) which yields another value (so that the
|
|
construction itself becomes an expression). So you can think of functions
|
|
or constructions that return a value (like print) as operators and those
|
|
that return nothing (like echo) as any other thing.
|
|
</simpara>
|
|
<para>
|
|
There are three types of operators. Firstly there is the unary operator which
|
|
operates on only one value, for example ! (the negation operator) or ++
|
|
(the increment operator). The second group are termed binary operators; this
|
|
group contains most of the operators that PHP supports, and a list follows
|
|
below in the section <link linkend="language.operators.precedence">Operator
|
|
Precedence</link>.
|
|
</para>
|
|
<para>
|
|
The third group is the ternary operator: ?:. It should be used to select
|
|
between two expressions depending on a third one, rather than to select two
|
|
sentences or paths of execution. Surrounding ternary expressions with
|
|
parentheses is a very good idea.
|
|
</para>
|
|
|
|
<sect1 id="language.operators.precedence">
|
|
<title>Operator Precedence</title>
|
|
<para>
|
|
The precedence of an operator specifies how "tightly" it binds two
|
|
expressions together. For example, in the expression <literal>1 +
|
|
5 * 3</literal>, the answer is <literal>16</literal> and not
|
|
<literal>18</literal> because the multiplication ("*") operator
|
|
has a higher precedence than the addition ("+") operator.
|
|
Parentheses may be used to force precedence, if necessary. For
|
|
instance: <literal>(1 + 5) * 3</literal> evaluates to
|
|
<literal>18</literal>. If operator precedence is equal, left to right
|
|
associativity is used.
|
|
</para>
|
|
<para>
|
|
The following table lists the precedence of operators with the
|
|
highest-precedence operators listed at the top of the table. Operators
|
|
on the same line have equal precedence, in which case their
|
|
associativity decides which order to evaluate them in.
|
|
<table>
|
|
<title>Operator Precedence</title>
|
|
<tgroup cols="2">
|
|
<thead>
|
|
<row>
|
|
<entry>Associativity</entry>
|
|
<entry>Operators</entry>
|
|
<entry>Additional Information</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>non-associative</entry>
|
|
<entry>new</entry>
|
|
<entry><link linkend="language.oop5.basic.new">new</link></entry>
|
|
</row>
|
|
<row>
|
|
<entry>left</entry>
|
|
<entry>[</entry>
|
|
<entry><function>array</function></entry>
|
|
</row>
|
|
<row>
|
|
<entry>non-associative</entry>
|
|
<entry>++ --</entry>
|
|
<entry>
|
|
<link linkend="language.operators.increment">increment/decrement</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>non-associative</entry>
|
|
<entry>~ - (int) (float) (string) (array) (object) @</entry>
|
|
<entry>
|
|
<link linkend="language.types">types</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>non-associative</entry>
|
|
<entry>instanceof</entry>
|
|
<entry>
|
|
<link linkend="language.types">types</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>right</entry>
|
|
<entry>!</entry>
|
|
<entry>
|
|
<link linkend="language.operators.logical">logical</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>left</entry>
|
|
<entry>* / %</entry>
|
|
<entry>
|
|
<link linkend="language.operators.arithmetic">arithmetic</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>left</entry>
|
|
<entry>+ - .</entry>
|
|
<entry>
|
|
<link linkend="language.operators.arithmetic">arithmetic</link>&listendand;
|
|
<link linkend="language.operators.string">string</link></entry>
|
|
</row>
|
|
<row>
|
|
<entry>left</entry>
|
|
<entry><< >></entry>
|
|
<entry>
|
|
<link linkend="language.operators.bitwise">bitwise</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>non-associative</entry>
|
|
<entry>< <= > >=</entry>
|
|
<entry>
|
|
<link linkend="language.operators.comparison">comparison</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>non-associative</entry>
|
|
<entry>== != === !==</entry>
|
|
<entry>
|
|
<link linkend="language.operators.comparison">comparison</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>left</entry>
|
|
<entry>&</entry>
|
|
<entry>
|
|
<link linkend="language.operators.bitwise">bitwise</link>&listendand;
|
|
<link linkend="language.references">references</link></entry>
|
|
</row>
|
|
<row>
|
|
<entry>left</entry>
|
|
<entry>^</entry>
|
|
<entry>
|
|
<link linkend="language.operators.bitwise">bitwise</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>left</entry>
|
|
<entry>|</entry>
|
|
<entry>
|
|
<link linkend="language.operators.bitwise">bitwise</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>left</entry>
|
|
<entry>&&</entry>
|
|
<entry>
|
|
<link linkend="language.operators.logical">logical</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>left</entry>
|
|
<entry>||</entry>
|
|
<entry>
|
|
<link linkend="language.operators.logical">logical</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>left</entry>
|
|
<entry>? :</entry>
|
|
<entry>
|
|
<link linkend="language.operators.comparison.ternary">ternary</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>right</entry>
|
|
<entry>
|
|
= += -= *= /= .= %= &= |= ^= <<= >>=
|
|
</entry>
|
|
<entry>
|
|
<link linkend="language.operators.assignment">assignment</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>left</entry>
|
|
<entry>and</entry>
|
|
<entry>
|
|
<link linkend="language.operators.logical">logical</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>left</entry>
|
|
<entry>xor</entry>
|
|
<entry>
|
|
<link linkend="language.operators.logical">logical</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>left</entry>
|
|
<entry>or</entry>
|
|
<entry>
|
|
<link linkend="language.operators.logical">logical</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>left</entry>
|
|
<entry>,</entry>
|
|
<entry>many uses</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
</para>
|
|
<para>
|
|
Left associativity means that the expression is evaluated from left to right,
|
|
right associativity means the opposite.
|
|
<example>
|
|
<title>Associativity</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$a = 3 * 3 % 5; // (3 * 3) % 5 = 4
|
|
$a = true ? 0 : true ? 1 : 2; // (true ? 0 : true) ? 1 : 2 = 2
|
|
|
|
$a = 1;
|
|
$b = 2;
|
|
$a = $b += 3; // $a = ($b += 3) -> $a = 5, $b = 5
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
Use parentheses to increase readability of the code.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Although <literal>=</literal> has a lower precedence than
|
|
most other operators, PHP will still allow expressions
|
|
similar to the following: <literal>if (!$a = foo())</literal>,
|
|
in which case the return value of <literal>foo()</literal> is
|
|
put into <varname>$a</varname>.
|
|
</para>
|
|
</note>
|
|
</sect1>
|
|
|
|
<sect1 id="language.operators.arithmetic">
|
|
<title>Arithmetic Operators</title>
|
|
<simpara>
|
|
Remember basic arithmetic from school? These work just
|
|
like those.
|
|
</simpara>
|
|
<table>
|
|
<title>Arithmetic Operators</title>
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>Example</entry>
|
|
<entry>Name</entry>
|
|
<entry>Result</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>-$a</entry>
|
|
<entry>Negation</entry>
|
|
<entry>Opposite of $a.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a + $b</entry>
|
|
<entry>Addition</entry>
|
|
<entry>Sum of $a and $b.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a - $b</entry>
|
|
<entry>Subtraction</entry>
|
|
<entry>Difference of $a and $b.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a * $b</entry>
|
|
<entry>Multiplication</entry>
|
|
<entry>Product of $a and $b.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a / $b</entry>
|
|
<entry>Division</entry>
|
|
<entry>Quotient of $a and $b.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a % $b</entry>
|
|
<entry>Modulus</entry>
|
|
<entry>Remainder of $a divided by $b.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<simpara>
|
|
The division operator ("/") returns a float value anytime,
|
|
even if the two operands are integers (or strings that get
|
|
converted to integers).
|
|
</simpara>
|
|
<note>
|
|
<simpara>
|
|
Remainder <literal>$a % $b</literal> is negative for negative
|
|
<literal>$a</literal>.
|
|
</simpara>
|
|
</note>
|
|
<simpara>
|
|
See also the manual page on
|
|
<link linkend="ref.math">Math functions</link>.
|
|
</simpara>
|
|
|
|
<!--
|
|
<simpara>
|
|
The division operator ("/") returns an integer value (the result
|
|
of an integer division) if the two operands are integers (or
|
|
strings that get converted to integers) and the quotient is an
|
|
integer. If either operand is a floating-point value, or the
|
|
operation results in a non-integer value, a floating-point value
|
|
is returned.
|
|
</simpara>
|
|
-->
|
|
</sect1>
|
|
|
|
<sect1 id="language.operators.assignment">
|
|
<title>Assignment Operators</title>
|
|
<simpara>
|
|
The basic assignment operator is "=". Your first inclination might
|
|
be to think of this as "equal to". Don't. It really means that the
|
|
left operand gets set to the value of the expression on the
|
|
rights (that is, "gets set to").
|
|
</simpara>
|
|
<para>
|
|
The value of an assignment expression is the value assigned. That
|
|
is, the value of "$a = 3" is 3. This allows you to do some tricky
|
|
things:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$a = ($b = 4) + 5; // $a is equal to 9 now, and $b has been set to 4.
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
In addition to the basic assignment operator, there are "combined
|
|
operators" for all of the <link linkend="language.operators">binary
|
|
arithmetic</link>, array union and string operators that allow you to use a value in an
|
|
expression and then set its value to the result of that expression. For
|
|
example:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$a = 3;
|
|
$a += 5; // sets $a to 8, as if we had said: $a = $a + 5;
|
|
$b = "Hello ";
|
|
$b .= "There!"; // sets $b to "Hello There!", just like $b = $b . "There!";
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
Note that the assignment copies the original variable to the new
|
|
one (assignment by value), so changes to one will not affect the
|
|
other. This may also have relevance if you need to copy something
|
|
like a large array inside a tight loop. Since PHP 4, assignment
|
|
by reference has been supported, using the <computeroutput>$var =
|
|
&$othervar;</computeroutput> syntax, but this is not possible
|
|
in PHP 3. 'Assignment by reference' means that both variables end
|
|
up pointing at the same data, and nothing is copied anywhere.
|
|
To learn more about references, please read <link
|
|
linkend="language.references">References explained</link>. As of
|
|
PHP 5, objects are assigned by reference unless explicitly told
|
|
otherwise with the new <link linkend="language.oop5.cloning">clone</link>
|
|
keyword.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 id="language.operators.bitwise">
|
|
<title>Bitwise Operators</title>
|
|
<simpara>
|
|
Bitwise operators allow you to turn specific bits within an
|
|
integer on or off. If both the left- and right-hand parameters are
|
|
strings, the bitwise operator will operate on the characters' ASCII
|
|
values.
|
|
</simpara>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
echo 12 ^ 9; // Outputs '5'
|
|
|
|
echo "12" ^ "9"; // Outputs the Backspace character (ascii 8)
|
|
// ('1' (ascii 49)) ^ ('9' (ascii 57)) = #8
|
|
|
|
echo "hallo" ^ "hello"; // Outputs the ascii values #0 #4 #0 #0 #0
|
|
// 'a' ^ 'e' = #4
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
|
|
<table>
|
|
<title>Bitwise Operators</title>
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>Example</entry>
|
|
<entry>Name</entry>
|
|
<entry>Result</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>$a & $b</entry>
|
|
<entry>And</entry>
|
|
<entry>Bits that are set in both $a and $b are set.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a | $b</entry>
|
|
<entry>Or</entry>
|
|
<entry>Bits that are set in either $a or $b are set.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a ^ $b</entry>
|
|
<entry>Xor</entry>
|
|
<entry>
|
|
Bits that are set in $a or $b but not both are set.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>~ $a</entry>
|
|
<entry>Not</entry>
|
|
<entry>
|
|
Bits that are set in $a are not set, and vice versa.
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a << $b</entry>
|
|
<entry>Shift left</entry>
|
|
<entry>
|
|
Shift the bits of $a $b steps to the left (each step means
|
|
"multiply by two")
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a >> $b</entry>
|
|
<entry>Shift right</entry>
|
|
<entry>
|
|
Shift the bits of $a $b steps to the right (each step means
|
|
"divide by two")
|
|
</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<warning>
|
|
<para>
|
|
Don't right shift for more than 32 bits on 32 bits systems. Don't left shift
|
|
in case it results to number longer than 32 bits.
|
|
</para>
|
|
</warning>
|
|
</sect1>
|
|
|
|
<sect1 id="language.operators.comparison">
|
|
<title>Comparison Operators</title>
|
|
<simpara>
|
|
Comparison operators, as their name implies, allow you to compare
|
|
two values. You may also be interested in viewing
|
|
<link linkend="types.comparisons">the type comparison tables</link>,
|
|
as they show examples of various type related comparisons.
|
|
</simpara>
|
|
<table>
|
|
<title>Comparison Operators</title>
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>Example</entry>
|
|
<entry>Name</entry>
|
|
<entry>Result</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>$a == $b</entry>
|
|
<entry>Equal</entry>
|
|
<entry>&true; if $a is equal to $b.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a === $b</entry>
|
|
<entry>Identical</entry>
|
|
<entry>
|
|
&true; if $a is equal to $b, and they are of the same
|
|
type. (introduced in PHP 4)
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a != $b</entry>
|
|
<entry>Not equal</entry>
|
|
<entry>&true; if $a is not equal to $b.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a <> $b</entry>
|
|
<entry>Not equal</entry>
|
|
<entry>&true; if $a is not equal to $b.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a !== $b</entry>
|
|
<entry>Not identical</entry>
|
|
<entry>
|
|
&true; if $a is not equal to $b, or they are not of the same
|
|
type. (introduced in PHP 4)
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a < $b</entry>
|
|
<entry>Less than</entry>
|
|
<entry>&true; if $a is strictly less than $b.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a > $b</entry>
|
|
<entry>Greater than</entry>
|
|
<entry>&true; if $a is strictly greater than $b.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a <= $b</entry>
|
|
<entry>Less than or equal to </entry>
|
|
<entry>&true; if $a is less than or equal to $b.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a >= $b</entry>
|
|
<entry>Greater than or equal to </entry>
|
|
<entry>&true; if $a is greater than or equal to $b.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<para>
|
|
If you compare an integer with a string, the string is
|
|
<link linkend="language.types.string.conversion">converted to a number</link>.
|
|
If you compare two numerical strings, they are compared as integers. These
|
|
rules also apply to the
|
|
<link linkend="control-structures.switch">switch</link> statement.
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
var_dump(0 == "a"); // 0 == 0 -> true
|
|
var_dump("1" == "01"); // 1 == 1 -> true
|
|
|
|
switch ("a") {
|
|
case 0:
|
|
echo "0";
|
|
break;
|
|
case "a": // never reached because "a" is already matched with 0
|
|
echo "a";
|
|
break;
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
|
|
<para>
|
|
For various types, comparison is done according to the following
|
|
table (in order).
|
|
</para>
|
|
<table id="language.operators.comparison.types">
|
|
<title>Comparison with Various Types</title>
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>Type of Operand 1</entry>
|
|
<entry>Type of Operand 2</entry>
|
|
<entry>Result</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry><type>null</type> or <type>string</type></entry>
|
|
<entry><type>string</type></entry>
|
|
<entry>Convert &null; to "", numerical or lexical comparison</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>bool</type> or <type>null</type></entry>
|
|
<entry>anything</entry>
|
|
<entry>Convert to <type>bool</type>, &false; < &true;</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>object</type></entry>
|
|
<entry><type>object</type></entry>
|
|
<entry>Built-in classes can define its own comparison, different classes
|
|
are uncomparable, same class - compare properties the same way as
|
|
arrays (PHP 4), PHP 5 has its own <link
|
|
linkend="language.oop5.object-comparison">explanation</link>
|
|
</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>string</type>, <type>resource</type> or <type>number</type></entry>
|
|
<entry><type>string</type>, <type>resource</type> or <type>number</type></entry>
|
|
<entry>Translate strings and resources to numbers, usual math</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>array</type></entry>
|
|
<entry><type>array</type></entry>
|
|
<entry>Array with fewer members is smaller, if key from operand 1 is not
|
|
found in operand 2 then arrays are uncomparable, otherwise - compare
|
|
value by value (see following example)</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>array</type></entry>
|
|
<entry>anything</entry>
|
|
<entry><type>array</type> is always greater</entry>
|
|
</row>
|
|
<row>
|
|
<entry><type>object</type></entry>
|
|
<entry>anything</entry>
|
|
<entry><type>object</type> is always greater</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<para>
|
|
<example>
|
|
<title>Transcription of standard array comparison</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// Arrays are compared like this with standard comparison operators
|
|
function standard_array_compare($op1, $op2)
|
|
{
|
|
if (count($op1) < count($op2)) {
|
|
return -1; // $op1 < $op2
|
|
} elseif (count($op1) > count($op2)) {
|
|
return 1; // $op1 > $op2
|
|
}
|
|
foreach ($op1 as $key => $val) {
|
|
if (!array_key_exists($key, $op2)) {
|
|
return null; // uncomparable
|
|
} elseif ($val < $op2[$key]) {
|
|
return -1;
|
|
} elseif ($val > $op2[$key]) {
|
|
return 1;
|
|
}
|
|
}
|
|
return 0; // $op1 == $op2
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
|
|
<para>
|
|
See also <function>strcasecmp</function>,
|
|
<function>strcmp</function>,
|
|
<link linkend="language.operators.array">Array operators</link>,
|
|
and the manual section on
|
|
<link linkend="language.types">Types</link>.
|
|
</para>
|
|
|
|
<sect2 id="language.operators.comparison.ternary">
|
|
<title>Ternary Operator</title>
|
|
<para>
|
|
Another conditional operator is the "?:" (or ternary) operator.
|
|
<example>
|
|
<title>Assigning a default value</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// Example usage for: Ternary Operator
|
|
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
|
|
|
|
// The above is identical to this if/else statement
|
|
if (empty($_POST['action'])) {
|
|
$action = 'default';
|
|
} else {
|
|
$action = $_POST['action'];
|
|
}
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
The expression <literal>(expr1) ? (expr2) : (expr3)</literal>
|
|
evaluates to <replaceable>expr2</replaceable> if
|
|
<replaceable>expr1</replaceable> evaluates to &true;, and
|
|
<replaceable>expr3</replaceable> if
|
|
<replaceable>expr1</replaceable> evaluates to &false;.
|
|
</para>
|
|
<note>
|
|
<simpara>
|
|
Please note that the ternary operator is a statement, and that it
|
|
doesn't evaluate to a variable, but to the result of a statement. This
|
|
is important to know if you want to return a variable by reference.
|
|
The statement <literal>return $var == 42 ? $a : $b;</literal> in a
|
|
return-by-reference function will therefore not work and a warning is
|
|
issued in later PHP versions.
|
|
</simpara>
|
|
</note>
|
|
<note>
|
|
<para>
|
|
Is is recommended that you avoid "stacking" ternary expressions. PHP's
|
|
behaviour when using more than one ternary operator within a single
|
|
statement is non-obvious:
|
|
<example>
|
|
<title>Non-obvious Ternary Behaviour</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
// on first glance, the following appears to output 'true'
|
|
echo (true?'true':false?'t':'f');
|
|
|
|
// however, the actual output of the above is 't'
|
|
// this is because ternary expressions are evaluated from left to right
|
|
|
|
// the following is a more obvious version of the same code as above
|
|
echo ((true ? 'true' : 'false') ? 't' : 'f');
|
|
|
|
// here, you can see that the first expression is evaluated to 'true', which
|
|
// in turn evaluates to (bool)true, thus returning the true branch of the
|
|
// second ternary expression.
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
</note>
|
|
</sect2>
|
|
|
|
</sect1>
|
|
|
|
<sect1 id="language.operators.errorcontrol">
|
|
<title>Error Control Operators</title>
|
|
<simpara>
|
|
PHP supports one error control operator: the at sign (@). When
|
|
prepended to an expression in PHP, any error messages that might
|
|
be generated by that expression will be ignored.
|
|
</simpara>
|
|
<simpara>
|
|
If the <link linkend="ini.track-errors"><option>track_errors</option></link>
|
|
feature is enabled, any error message generated by the expression
|
|
will be saved in the variable
|
|
<link linkend="reserved.variables.phperrormsg">$php_errormsg</link>.
|
|
This variable will be overwritten on each error, so check early if you
|
|
want to use it.
|
|
</simpara>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
/* Intentional file error */
|
|
$my_file = @file ('non_existent_file') or
|
|
die ("Failed opening file: error was '$php_errormsg'");
|
|
|
|
// this works for any expression, not just functions:
|
|
$value = @$cache[$key];
|
|
// will not issue a notice if the index $key doesn't exist.
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<note>
|
|
<simpara>
|
|
The @-operator works only on
|
|
<link linkend="language.expressions">expressions</link>. A simple rule
|
|
of thumb is: if you can take the value of something, you can prepend
|
|
the @ operator to it. For instance, you can prepend it to variables,
|
|
function and <function>include</function> calls, constants, and
|
|
so forth. You cannot prepend it to function or class definitions,
|
|
or conditional structures such as <literal>if</literal> and
|
|
<literal>foreach</literal>, and so forth.
|
|
</simpara>
|
|
</note>
|
|
<simpara>
|
|
See also <function>error_reporting</function> and the manual section for
|
|
<link linkend="ref.errorfunc">Error Handling and Logging functions</link>.
|
|
</simpara>
|
|
<warning>
|
|
<para>
|
|
Currently the "@" error-control operator prefix will even disable
|
|
error reporting for critical errors that will terminate script
|
|
execution. Among other things, this means that if you use "@" to
|
|
suppress errors from a certain function and either it isn't
|
|
available or has been mistyped, the script will die right there
|
|
with no indication as to why.
|
|
</para>
|
|
</warning>
|
|
</sect1>
|
|
|
|
<sect1 id="language.operators.execution">
|
|
<title>Execution Operators</title>
|
|
<para>
|
|
PHP supports one execution operator: backticks (``). Note that
|
|
these are not single-quotes! PHP will attempt to execute the
|
|
contents of the backticks as a shell command; the output will be
|
|
returned (i.e., it won't simply be dumped to output; it can be
|
|
assigned to a variable). Use of the backtick operator is identical
|
|
to <function>shell_exec</function>.
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$output = `ls -al`;
|
|
echo "<pre>$output</pre>";
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<note>
|
|
<para>
|
|
The backtick operator is disabled when &safemode; is enabled
|
|
or <function>shell_exec</function> is disabled.
|
|
</para>
|
|
</note>
|
|
<para>
|
|
See also the manual section on <link linkend="ref.exec">Program
|
|
Execution functions</link>, <function>popen</function>
|
|
<function>proc_open</function>, and
|
|
<link linkend="features.commandline">Using PHP from the
|
|
commandline</link>.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 id="language.operators.increment">
|
|
<title>Incrementing/Decrementing Operators</title>
|
|
<para>
|
|
PHP supports C-style pre- and post-increment and decrement
|
|
operators.
|
|
</para>
|
|
<note>
|
|
<simpara>
|
|
The increment/decrement operators do not affect boolean values.
|
|
Decrementing &null; values has no effect too, but incrementing them
|
|
results in <literal>1</literal>.
|
|
</simpara>
|
|
</note>
|
|
<table>
|
|
<title>Increment/decrement Operators</title>
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>Example</entry>
|
|
<entry>Name</entry>
|
|
<entry>Effect</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>++$a</entry>
|
|
<entry>Pre-increment</entry>
|
|
<entry>Increments $a by one, then returns $a.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a++</entry>
|
|
<entry>Post-increment</entry>
|
|
<entry>Returns $a, then increments $a by one.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>--$a</entry>
|
|
<entry>Pre-decrement</entry>
|
|
<entry>Decrements $a by one, then returns $a.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a--</entry>
|
|
<entry>Post-decrement</entry>
|
|
<entry>Returns $a, then decrements $a by one.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<para>
|
|
Here's a simple example script:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
echo "<h3>Postincrement</h3>";
|
|
$a = 5;
|
|
echo "Should be 5: " . $a++ . "<br />\n";
|
|
echo "Should be 6: " . $a . "<br />\n";
|
|
|
|
echo "<h3>Preincrement</h3>";
|
|
$a = 5;
|
|
echo "Should be 6: " . ++$a . "<br />\n";
|
|
echo "Should be 6: " . $a . "<br />\n";
|
|
|
|
echo "<h3>Postdecrement</h3>";
|
|
$a = 5;
|
|
echo "Should be 5: " . $a-- . "<br />\n";
|
|
echo "Should be 4: " . $a . "<br />\n";
|
|
|
|
echo "<h3>Predecrement</h3>";
|
|
$a = 5;
|
|
echo "Should be 4: " . --$a . "<br />\n";
|
|
echo "Should be 4: " . $a . "<br />\n";
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
PHP follows Perl's convention when dealing with arithmetic operations
|
|
on character variables and not C's. For example, in Perl 'Z'+1 turns
|
|
into 'AA', while in C 'Z'+1 turns into '[' ( ord('Z') == 90, ord('[') == 91 ).
|
|
Note that character variables can be incremented but not decremented and
|
|
even so only plain ASCII characters (a-z and A-Z) are supported.
|
|
<example>
|
|
<title>Arithmetic Operations on Character Variables</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$i = 'W';
|
|
for ($n=0; $n<6; $n++) {
|
|
echo ++$i . "\n";
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
X
|
|
Y
|
|
Z
|
|
AA
|
|
AB
|
|
AC
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Incrementing or decrementing booleans has no effect.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 id="language.operators.logical">
|
|
<title>Logical Operators</title>
|
|
|
|
<table>
|
|
<title>Logical Operators</title>
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>Example</entry>
|
|
<entry>Name</entry>
|
|
<entry>Result</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>$a and $b</entry>
|
|
<entry>And</entry>
|
|
<entry>&true; if both $a and $b are &true;.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a or $b</entry>
|
|
<entry>Or</entry>
|
|
<entry>&true; if either $a or $b is &true;.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a xor $b</entry>
|
|
<entry>Xor</entry>
|
|
<entry>&true; if either $a or $b is &true;, but not both.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>! $a</entry>
|
|
<entry>Not</entry>
|
|
<entry>&true; if $a is not &true;.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a && $b</entry>
|
|
<entry>And</entry>
|
|
<entry>&true; if both $a and $b are &true;.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a || $b</entry>
|
|
<entry>Or</entry>
|
|
<entry>&true; if either $a or $b is &true;.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<simpara>
|
|
The reason for the two different variations of "and" and "or"
|
|
operators is that they operate at different precedences. (See
|
|
<link linkend="language.operators.precedence">Operator
|
|
Precedence</link>.)
|
|
</simpara>
|
|
</sect1>
|
|
|
|
<sect1 id="language.operators.string">
|
|
<title>String Operators</title>
|
|
<simpara>
|
|
There are two <type>string</type> operators. The first is the
|
|
concatenation operator ('.'), which returns the concatenation of its
|
|
right and left arguments. The second is the concatenating assignment
|
|
operator ('.='), which appends the argument on the right side to
|
|
the argument on the left side. Please read <link
|
|
linkend="language.operators.assignment">Assignment
|
|
Operators</link> for more information.
|
|
</simpara>
|
|
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$a = "Hello ";
|
|
$b = $a . "World!"; // now $b contains "Hello World!"
|
|
|
|
$a = "Hello ";
|
|
$a .= "World!"; // now $a contains "Hello World!"
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
See also the manual sections on the
|
|
<link linkend="language.types.string">String type</link> and
|
|
<link linkend="ref.strings">String functions</link>.
|
|
</para>
|
|
</sect1>
|
|
|
|
<sect1 id="language.operators.array">
|
|
<title>Array Operators</title>
|
|
<table>
|
|
<title>Array Operators</title>
|
|
<tgroup cols="3">
|
|
<thead>
|
|
<row>
|
|
<entry>Example</entry>
|
|
<entry>Name</entry>
|
|
<entry>Result</entry>
|
|
</row>
|
|
</thead>
|
|
<tbody>
|
|
<row>
|
|
<entry>$a + $b</entry>
|
|
<entry>Union</entry>
|
|
<entry>Union of $a and $b.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a == $b</entry>
|
|
<entry>Equality</entry>
|
|
<entry>&true; if $a and $b have the same key/value pairs.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a === $b</entry>
|
|
<entry>Identity</entry>
|
|
<entry>&true; if $a and $b have the same key/value pairs in the same
|
|
order and of the same types.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a != $b</entry>
|
|
<entry>Inequality</entry>
|
|
<entry>&true; if $a is not equal to $b.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a <> $b</entry>
|
|
<entry>Inequality</entry>
|
|
<entry>&true; if $a is not equal to $b.</entry>
|
|
</row>
|
|
<row>
|
|
<entry>$a !== $b</entry>
|
|
<entry>Non-identity</entry>
|
|
<entry>&true; if $a is not identical to $b.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</table>
|
|
<para>
|
|
The <literal>+</literal> operator
|
|
appends the right handed array to the left handed, whereas
|
|
duplicated keys are NOT overwritten.
|
|
</para>
|
|
<para>
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$a = array("a" => "apple", "b" => "banana");
|
|
$b = array("a" => "pear", "b" => "strawberry", "c" => "cherry");
|
|
|
|
$c = $a + $b; // Union of $a and $b
|
|
echo "Union of \$a and \$b: \n";
|
|
var_dump($c);
|
|
|
|
$c = $b + $a; // Union of $b and $a
|
|
echo "Union of \$b and \$a: \n";
|
|
var_dump($c);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
When executed, this script will print the following:
|
|
<screen role="php">
|
|
<![CDATA[
|
|
Union of $a and $b:
|
|
array(3) {
|
|
["a"]=>
|
|
string(5) "apple"
|
|
["b"]=>
|
|
string(6) "banana"
|
|
["c"]=>
|
|
string(6) "cherry"
|
|
}
|
|
Union of $b and $a:
|
|
array(3) {
|
|
["a"]=>
|
|
string(4) "pear"
|
|
["b"]=>
|
|
string(10) "strawberry"
|
|
["c"]=>
|
|
string(6) "cherry"
|
|
}
|
|
]]>
|
|
</screen>
|
|
</para>
|
|
<para>
|
|
Elements of arrays are equal for the comparison if they have the
|
|
same key and value.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Comparing arrays</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$a = array("apple", "banana");
|
|
$b = array(1 => "banana", "0" => "apple");
|
|
|
|
var_dump($a == $b); // bool(true)
|
|
var_dump($a === $b); // bool(false)
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
See also the manual sections on the
|
|
<link linkend="language.types.array">Array type</link> and
|
|
<link linkend="ref.array">Array functions</link>.
|
|
</para>
|
|
</sect1>
|
|
<sect1 id="language.operators.type">
|
|
<title>Type Operators</title>
|
|
<para>
|
|
<literal>instanceof</literal> is used to determine whether a PHP variable
|
|
is an instantiated object of a certain
|
|
<link linkend="language.oop5.basic.class">class</link>:
|
|
<example>
|
|
<title>Using instanceof with classes</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class MyClass
|
|
{
|
|
}
|
|
class NotMyClass
|
|
{
|
|
}
|
|
$a = new MyClass;
|
|
|
|
var_dump($a instanceof MyClass);
|
|
var_dump($a instanceof NotMyClass);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
bool(true)
|
|
bool(false)
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
<literal>instanceof</literal> can also be used to determine whether a variable
|
|
is an instantiated object of a class that inherits from a parent class:
|
|
<example>
|
|
<title>Using instanceof with inherited classes</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
class ParentClass
|
|
{
|
|
}
|
|
class MyClass extends ParentClass
|
|
{
|
|
}
|
|
$a = new MyClass;
|
|
|
|
var_dump($a instanceof MyClass);
|
|
var_dump($a instanceof ParentClass);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
bool(true)
|
|
bool(true)
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
Lastly, <literal>instanceof</literal> can also be used to determine whether
|
|
a variable is an instantiated object of a class that implements an
|
|
<link linkend="language.oop5.interfaces">interface</link>:
|
|
<example>
|
|
<title>Using instanceof for class</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
interface MyInterface
|
|
{
|
|
}
|
|
class MyClass implements MyInterface
|
|
{
|
|
}
|
|
$a = new MyClass;
|
|
|
|
var_dump($a instanceof MyClass);
|
|
var_dump($a instanceof MyInterface);
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
bool(true)
|
|
bool(true)
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
Although <literal>instanceof</literal> is usually used with a literal classname,
|
|
it can also be used with another object or a string variable:
|
|
<example>
|
|
<title>Using instanceof with other variables</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
interface MyInterface
|
|
{
|
|
}
|
|
class MyClass implements MyInterface
|
|
{
|
|
}
|
|
$a = new MyClass;
|
|
$b = new MyClass;
|
|
$c = 'MyClass';
|
|
$d = 'NotMyClass';
|
|
var_dump($a instanceof $b); // $b is an object of class MyClass
|
|
var_dump($a instanceof $c); // $c is a string 'MyClass'
|
|
var_dump($a instanceof $d); // $d is a string 'NotMyClass'
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
bool(true)
|
|
bool(true)
|
|
bool(false)
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<para>
|
|
There are a few pitfalls to be aware of. Before PHP version 5.1.0,
|
|
<literal>instanceof</literal> would call <link linkend="language.oop5.autoload">__autoload()</link>
|
|
if the class name did not exist. In addition, if the class was not loaded,
|
|
a fatal error would occur. This can be worked around by using a <literal>dynamic
|
|
class reference</literal>, or a string variable containing the class name:
|
|
<example>
|
|
<title>Avoiding classname lookups and fatal errors with instanceof in PHP 5.0</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$d = 'NotMyClass';
|
|
var_dump($a instanceof $d); // no fatal error here
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
&example.outputs;
|
|
<screen>
|
|
<![CDATA[
|
|
bool(false)
|
|
]]>
|
|
</screen>
|
|
</example>
|
|
</para>
|
|
<simpara>
|
|
The <literal>instanceof</literal> operator was introduced in PHP 5.
|
|
Before this time <function>is_a</function> was used but
|
|
<function>is_a</function> has since been deprecated in favor of
|
|
<literal>instanceof</literal>.
|
|
</simpara>
|
|
<para>
|
|
See also <function>get_class</function> and
|
|
<function>is_a</function>.
|
|
</para>
|
|
</sect1>
|
|
</chapter>
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:t
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
indent-tabs-mode:nil
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"../../manual.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|