Документация
HTML CSS PHP PERL другое

Expressions and Operators

 
Previous
Table of Contents
Next

Expressions and Operators

PHP is sometimes called an expression-oriented language, since a vast majority of things you do in PHP have a value associated with them. Even assigning a value to a variable is an expression that has a valuethat of the value assigned. Functions are expressions whose value is the return value of the function. Some thingsfor example, control structures and special methods such as echodo not have values.

Operators: Combining Expressions

You can combine expressions to make new ones by using operators. PHP is extremely rich in operators that can provide all sorts of ways to combine expressions (or variables) of different types.

Assignment

An assignment statement is a very simple expression. You can take the result of an assignment and use it in another expression or even another assignment.

<?php
  // these three clusters of statements have the same effect...
  // both $a and $b end up with the value 5.
  $a = 5; $b = 5;
  $a = $b = 5;

  $b = $a = 5;
?>

The fact that an assignment has an expression is what lets programmers incorporate assignments into some control structures, such as the loop that follows:

<?php

  while (($user_name = get_next_logged_in_user()) !== FALSE)
  {
    echo "<b>$user_name</b> is currently logged in!<br/>\n";
  }

?>

Arithmetic Operators

PHP has a complete set of arithmetic operators that operate on integers and floats. Operands that are not of the correct type are converted to one of these types and evaluated.

The following operators are supported:

Operator

Example

Description

+

$a + $b

Addition: The result is the sum of the operands.

$a $b

Subtraction: The result is the difference of the operands.

*

$a * $b

Multiplication: The result is the product of the two operands.

/

$a / $b

Division: The result is the quotient of the two operands.

%

$a % $b

Modulus: The result is the remainder of division performed on the two operands.


As we mentioned in Chapter 1, there is no integer division in PHP. Division that results in a noninteger quotient simply returns a float.

For all operators, there is also an assigning version of it, where the left operand is also the variable location to place the result.

<?php

  $a = 10;
  $a *= 10;             // $a is now 100
  $b = 100;
  $b /= 30;             // $b is now 3.33333...
  $b += 1;              // $b is now 4.33333...
  $a -= 99;             // $a is now 1
  $c = 5;
  $c %= 3;              // $c is now 2
?>

Comparison Operators

The operators used for comparison in PHP allow us to compare the values of two expressions or simple values. They always evaluate to a Boolean value and indicate the result of the comparison, as follows:

Operator

Example

Description

==

$a == $b

Equality: This returns TRUE whether the two operands have the same value or not.

===

$a === $b

Identity: This evaluates to trUE if the two operands have the same value and are the same type.

!=

$a != $b

Inequality: This evaluates to trUE if the two operands do not have the same value.

<>

$a <> $b

Inequality: This evaluates to TRUE if the two operands do not have the same value.

!==

$a !== $b

Non-identity: This evaluates to TRUE if the two operands do not have the same value or are not the same type.

<

$a < $b

Less than: This evaluates to trUE if the left-side operand has a value less than that on the right.

>

$a > $b

Greater than: This evaluates to trUE if the left-side operand has a value greater than the operand on the right.

<=

$a <= $b

Less than or equal: This evaluates to TRUE if the left-side operand has a value less than or equal to that on the right.

>=

$a >= $b

Greater than or equal: This evaluates to TRUE if the left-side operand has a value greater than or equal to that of the operand on the right.


The difference between the equality and identity operators deserves further attention. The former (==) merely checks to see if the two operands have the same value, even if they are not of the same type, while the latter only returns trUE if they are the same value and of the same type.

"123" == 123       <-- TRUE
"123" === 123      <-- FALSE
"123" === "123"    <-- TRUE
TRUE == "Honk!"    <-- TRUE
TRUE === "Honk!"   <-- FALSE

There is another comparison operator in PHP that can prove useful in organizing your code: the ?: or ternary operator, which has the following syntax:

expression1 ? expression2 : expression3

The ?: operator evaluates expression1 and then looks at the resulting value. If it evaluates to TRUE (whether directly or via conversion), then the value of the ?: expression is the result of evaluating expression2. Otherwise, the value or result of the ?: operator is the result of evaluating expression3.

<?php

  $shipping_weight = 8.5;
  $shipping_time = ($shipping_weight < 10) ? 48 : 72;

  // a customs form is required since destination isn't USA.
  $shipping_country = "Japan";
  $customs_form_required = ($shipping_country != "USA")
                           ? TRUE : FALSE;

?>

The sharp reader might have noticed that the last statement in the previous expression could simply be written as

$customs_form_required = $shipping_country != "USA";

And it would behave the same. However, we typically opt for explicitness in this book, to make code clearer and help reduce chances for confusion.

Logical Operators

A set of operators that you will commonly use are the logical operators, which let you compare the results of two expressions.

Operator

Example

Description

and

$a and $b

And: This returns trUE if both operands evaluate to trUE.

&&

$a && $b

This is another way of writing the and operator.

or

$a or $b

Or: This evaluates to trUE if either operand evaluates to TRUE.

||

$a || $b

This is simply another way of writing the or operator.

xor

$a xor $b

Xor: This evaluates to trUE if one operand evaluates to trUE but not both.

!

! $a

Not: This evaluates to TRUE if $a evaluates to FALSE.


Logical operators in PHP evaluate from left to right and stop evaluating as soon as they can determine a value for the entire expression. Thus, in the example that follows:

<?php

    $a = TRUE;

    if ($a or some_function_call())
         ...

    if ((!$a) and some_other_function())
         ...
?>

Neither some_function_call nor some_other_function in the expressions are evaluated because the testing of the first operand in the expression determined a value for the entire expression.

Bitwise Operators

PHP comes with a full set of bitwise operators for manipulating individual bits on integer values. Although they are not used as often as other operators, we cover them here. If either of the operands is not an integer, it is first converted to one, and then the operation is performed. The only exception to this is if both operands are strings, in which case the operator operates on the individual characters' values.

Operator

Example

Description

&

$a & $b

And: This returns bits that are set in both $a and $b.

|

$a | $b

Or: This returns bits that are set in either $a or $b.

^

$a ^ $b

Xor: This returns bits that are set in either $a or $b, but not both.

~

~ $a

Not: This returns the bits that are not set in $a.

<<

$a << $b

Shift left: This shifts the bits in $a left by $b bits.

>>

$a >> $b

Shift right: This shifts the bits in $a right by $b bits.


Bitwise operators operate on the underlying binary representations of numbers. Most modern computers are binary computers, where numbers are stored and represented in binary format. Numbers are represented as streams of 0 or 1, with each new digit representing a new power of 2 (just like each new digit in a decimal number represents a new power of 10). For example, the number 4 in binary is 100, the number 5 is 101, and the number 23433 is 101101110001001.

Here are some examples of the binary operators in action:

<?php

  $x = 4;                   // 100 in binary
  $y = 3;                   //  11 in binary
  $z = 1;                   //   1 in binary
  $a = $x | $y;             // $a is 111
  $b = $x & $y;             // $b is 0 (no common bits)
  $c = $x ^ $z;             // $c is 101
  $d = ~ $x;                // see text
  $e = $x >> 2;             // $e is 1 
  $f = $y << 4;             // $f is 110000

?>

In the previous example, the only item that might be unusual is the assignment of ~ $a to the variable $d. In this, PHP and the underlying binary hardware take the 32-bit integer holding the value 100 and invert the values of all 32 bits. Whereas we started with a 32-bit value with one bit turned on representing the number 4, we end up with a 32-bit value with all bits turned on except 1 (which corresponds to the (signed) decimal value -5) after using the ~ operator.

For these operators, there are also assigning versions of them, where the left operand is also the variable location to place the result.

<?php

  $a &= b;                // equiv to  $a = $a & $b;
  $a >>= 6;               // equiv to  $a = $a >> 6;
  // etc.

?>

String Operators

There are two operators on strings available in PHP that return strings themselves.

The first is the concatenation operator (.), which takes two strings and returns a single string consisting of the two put together. The second operator is the concatenation and assignment operator (.=), which takes a string, concatenates another string to the end of it, and then assigns the value back to the variable in which the first string was previously held.

<?php

  // $a ends up with "Jacques logged in from Quebec"
  $a = "Jaques" . " logged in from Quebec";

  // $b will contain "Tang from Shanghai is currently active"
  $b = "Tang";
  $b .= " from Shanghai is currently active";

?>

Array Operators

A few of the operators discussed previously have different behaviors for arrays, which we will now briefly mention.

Operator

Example

Description

+

$ar1 + $ar2

Union: This returns an array containing the union of the keys/indices of the two operand arrays.

==

$ar1 == $ar2

Equality: This evaluates to trUE if the two arrays have the same element values associated with the same keys (possibly with different orderings).

!=

$ar1 != $ar2

Inequality: This evaluates to trUE if either array has a key/value pair that the other does not.

<>

$ar1 <> $ar2

Inequality: This evaluates to trUE if either array has a key/value pair that the other does not.

===

$ar1 === $ar2

Identity: This evaluates to TRUE if the two arrays have the same keys and elements in the same order.

!==

$ar1 !== $ar2

Non-identity: This evaluates to trUE if the two arrays are not identical.


Following are examples of these in use:

<?php

  $a1 = array(1, 2, 3);
  $a2 = array(2 => 3, 1 => 2, 0 => 1);
  $a3 = array(4, 5, 6);

  $a4 = $a1 + $a3;       // contains 1, 2, 3
  $a5 = ($a1 == $a2);    // TRUE: same values at same keys
  $a6 = ($a1 === $a2);   // FALSE: same key/values,
                         //        NOT same order

?>

The only unusual example in the previous code is the result of adding $a1 and $a3in this case, both arrays have three elements at index 0, 1, and 2. Therefore, the + operator takes the values for these keys from the first array and generates the resulting array for them. (We do not get the values 1 through 6 in the resulting array because the + operator worries about keys/indices, not values.)

Other Operators

Here are a few other operators that you will likely use.

PHP has auto-increment and auto-decrement operators, which take an integer value and increment or decrement its value by 1. They have the additional property of being able to do this before or after the evaluation formed by the variable and the operator is assessed.

The preincrement and predecrement operators (++$var and $var) increment or decrement the value of the integer and then return the newly adjusted value as the value of the expression. Conversely, the postincrement and postdecrement operators ($var++ and $var) increment or decrement the value of an integer after performing the operation of returning the value held in the variable.

<?php

  $a = 10;
  $b = $a++;               // $b is 10, $a is now 11
  $c = ++$a;               // $c is 12, $a is now 12
  $d = $a--;               // $d is 12, $a is now 11
  $e = --$a;               // $e is 10, $a is now 10

?>

There is also an operator called @, which tells PHP to ignore the failure of a particular function call. Normally, if a call to a function to do something (for example, to open a database connection or a file on the hard disk) fails, PHP automatically prints an error on the output stream. The @ operator tells PHP to ignore the result and continue processing (presumably because the programmer has written good code and will perform his own error checking and reporting).

<?php

  // $users will have the value NULL, and no error will
  // be printed
  $users = @file('i do not have permissions for this file');

?>

We shall return to the topic of errors more in Chapter 18, "Error Handling and Debugging."

There is one final operatorone that we will not often usecalled the shell command executor. To use this, you wrap a command with back-ticks ( `), and the text is then passed to a shell for execution. (This is similar to the backtick operator seen in Perl and Unix shell scripts.)

$text = `/bin/date`;     // $text holds output of date cmd

However, this is a good way to get into trouble with security. If you ever pass user input to this, you are opening your scripts to serious security problems, so be extraordinarily careful when using it.

Combining Expressions and Operator Precedence

The ability to form new expressions by combining existing expressions is a useful and often necessary feature of a programming language. To help you understand how this is done, PHP provides the ability to wrap expressions in parentheses (()). Doing this tells PHP to evaluate the expression(s) inside the parentheses as a unit before moving on and evaluating any neighboring expressions.

($a) == ($b)            // trivial case 
($a or $b) and $c       // evaluate $a or $b first, then
                        //   _result_ and $c
(($a and $b) xor ($d or $e)) or $f

For those cases where you do not use parentheses, PHP has a well-defined order of evaluation for complex expressions involving subexpressions and nested expressions. The order is listed in the following table, but we will prefix this discussion by encouraging you, the programmers, to make liberal use of parentheses and other devices to disambiguate complicated expressions instead of relying on this behavior. We say this for your own sanity and for the sanity of future programmers who might need to look at the code.

This will also save you troubles when PHP differs slightly from other languages with which you might be familiarPHP places a different priority (also known as associativity) on the subexpressions of the ternary operator ?: than other languages.

In the following table, the operators are arranged by importance, with the top being the highest. The associativity of an operator indicates whether PHP looks to the left or to the right of the operator for other items with which to build more expressions. Operators that share the same level of priority are evaluated in the order they are encountered by the PHP language processorleft to right.

Associativity

Operators

n/a

new (see Chapter 2, "The PHP Language")

right

[ (for arrays)

right

! ~ ++ @ type casts

left

* / %

left

+ .

left

<< >>

n/a

< <= > >=

n/a

== != <> === !==

left

&

left

^

left

|

left

&&

left

||

left

?:

right

= += = *= /= .= %= &= |= ^= <<= >>=

right

Print

left

And

left

Xor

left

Or

left

,


For example, the table tells us that

$a || $b + $c * $d and $e

is equivalent to

$a || (($b + ($c * $d)) and $e))

The following is even trickier. The confusion comes from trying to understand whether PHP treats the following

$a ? $b : $c ? $d : $e   

as either the first or second of

a.  ($a ? $b : $c) ? $d : $e
b.  $a ? $b : ($c ? $d : $e)

The associativity of the left ?: operator tells us that PHP will start at the left to build up a ternary grouping and continue toward the right, meaning it will execute (a).

Again, save yourself the trouble of debugging these problems. Use the parentheses.


Previous
Table of Contents
Next
© 2000- NIV