#
Learning Resources

## PHP Operators assignment arithmetic comparison and string

An expression *4 + 5 is equal to 9*. Here 4 and 5 are called operands and + is called operator. PHP language supports following type of operators.

- Arithmetic Operators
- Assignment Operators
- Bitwise Operators
- Comparison Operators
- Error Control Operators
- Execution Operators
- Incrementing/Decrementing Operators
- Logical Operators
- String Operators
- Array Operators
- Type Operators

An operator is something that takes one or more values (or expressions, in programming jargon) and yields another value (so that the construction itself becomes an expression).

Operators can be grouped according to the number of values they take. Unary operators take only one value, for example ! (the logical not operator) or ++ (the increment operator). Binary operators take two values, such as the familiar arithmetical operators + (plus) and - (minus), and the majority of PHP operators fall into this category. Finally, there is a single ternary operator, ? :, which takes three values; this is usually referred to simply as "the ternary operator" (although it could perhaps more properly be called the conditional operator).

## Operator Precedence

The precedence of an operator specifies how "tightly" it binds two expressions together. For example, in the expression *1 + 5 * 3*, the answer is *16* and not *18* because the multiplication ("*") operator has a higher precedence than the addition ("+") operator. Parentheses may be used to force precedence, if necessary. For instance: *(1 + 5) * 3* evaluates to *18*.

When operators have equal precedence, their associativity decides whether they are evaluated starting from the right, or starting from the left - see the examples below.

The following table lists the operators in order of precedence, with the highest-precedence ones at the top. Operators on the same line have equal precedence, in which case associativity decides the order of evaluation.

Associativity | Operators | Additional Information |
---|---|---|

non-associative | clone new | clone and new |

left | [ | array() |

right | ++ -- ~ (int) (float) (string) (array) (object) (bool) @ | types and increment/decrement |

non-associative | instanceof | types |

right | ! | logical |

left | * / % | arithmetic |

left | + - . | arithmetic and string |

left | << >> | bitwise |

non-associative | < <= > >= | comparison |

non-associative | == != === !== <> | comparison |

left | & | bitwise and references |

left | ^ | bitwise |

left | | | bitwise |

left | && | logical |

left | || | logical |

left | ? : | ternary |

right | = += -= *= /= .= %= &= |= ^= <<= >>= => | assignment |

left | and | logical |

left | xor | logical |

left | or | logical |

left | , | many uses |

For operators of equal precedence, left associativity means that evaluation proceeds from left to right, and right associativity means the opposite.

**Example #1 Associativity**

```
$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

// mixing ++ and + produces undefined behavior

$a = 1;

echo ++$a + $a++; // may print 4 or 5

?>

$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

// mixing ++ and + produces undefined behavior

$a = 1;

echo ++$a + $a++; // may print 4 or 5

?>

Use of parentheses, even when not strictly necessary, can often increase readability of the code.

## Arithmetic Operators

Remember basic arithmetic from school? These work just like those.

Example | Name | Result |
---|---|---|

-$a | Negation |
Opposite of .$a |

$a + $b | Addition |
Sum of and $a.$b |

$a - $b | Subtraction |
Difference of and $a.$b |

$a * $b | Multiplication |
Product of and $a.$b |

$a / $b | Division |
Quotient of and $a.$b |

$a % $b | Modulus |
Remainder of divided by $a.$b |

The division operator ("/") returns a float value unless the two operands are integers (or strings that get converted to integers) and the numbers are evenly divisible, in which case an integer value will be returned.

Operands of modulus are converted to integers (by stripping the decimal part) before processing.

The result of the modulus operator *%* has the same sign as the dividend — that is, the result of *$a % $b* will have the same sign as ` $a`. For example:

echo (5 % 3)."\n"; // prints 2

echo (5 % -3)."\n"; // prints 2

echo (-5 % 3)."\n"; // prints -2

echo (-5 % -3)."\n"; // prints -2

?>

## Assignment Operators

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 right (that is, "gets set to").

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:

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

?>

For arrays, assigning a value to a named key is performed using the "=>" operator. The precedence of this operator is the same as other assignment operators.

In addition to the basic assignment operator, there are "combined operators" for all of the binary arithmetic, 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:

$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!";

?>

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.

An exception to the usual assignment by value behaviour within PHP occurs with objects, which are assigned by reference in PHP 5. Objects may be explicitly copied via the clone keyword.

**Assignment by Reference**

Assignment by reference is also supported, using the "$var = &$othervar;" syntax. Assignment by reference means that both variables end up pointing at the same data, and nothing is copied anywhere.

Example #1 Assigning by reference

$a = 3;

$b = &$a; // $b is a reference to $a

print "$a\n"; // prints 3

print "$b\n"; // prints 3

$a = 4; // change $a

print "$a\n"; // prints 4

print "$b\n"; // prints 4 as well, since $b is a reference to $a, which has

// been changed

?>

As of PHP 5, the new operator returns a reference automatically, so assigning the result of new by reference results in an E_DEPRECATED message in PHP 5.3 and later, and an E_STRICT message in earlier versions.

For example, this code will result in a warning:

class C {}

/* The following line generates the following error message:

* Deprecated: Assigning the return value of new by reference is deprecated in...

*/

$o = &new C;

?>

### Bitwise Operators

Bitwise operators allow evaluation and manipulation of specific bits within an integer.

Example | Name | Result |
---|---|---|

`$a & $b` |
And |
Bits that are set in both and $a are set.$b |

`$a | $b` |
Or (inclusive or) |
Bits that are set in either or $a are set.$b |

`$a ^ $b` |
Xor (exclusive or) |
Bits that are set in or $a but not both are set.$b |

`~ $a` |
Not |
Bits that are set in are not set, and vice versa.$a |

`$a << $b` |
Shift left |
Shift the bits of $a steps to the left (each step means "multiply by two")$b |

`$a >> $b` |
Shift right |
Shift the bits of $a steps to the right (each step means "divide by two")$b |

Bit shifting in PHP is arithmetic. Bits shifted off either end are discarded. Left shifts have zeros shifted in on the right while the sign bit is shifted out on the left, meaning the sign of an operand is not preserved. Right shifts have copies of the sign bit shifted in on the left, meaning the sign of an operand is preserved.

Use parentheses to ensure the desired precedence. For example, $a & $b == true evaluates the equivalency then the bitwise and; while ($a & $b) == true evaluates the bitwise and then the equivalency.

Be aware of data type conversions. If both the left-hand and right-hand parameters are strings, the bitwise operator will operate on the characters' ASCII values.

PHP's error_reporting ini setting uses bitwise values,

providing a real-world demonstration of turning

bits off. To show all errors, except for notices,

the php.ini file instructions say to use:

E_ALL & ~E_NOTICE

This works by starting with E_ALL:

00000000000000000111011111111111

Then taking the value of E_NOTICE...

00000000000000000000000000001000

... and inverting it via ~:

11111111111111111111111111110111

Finally, it uses AND (&) to find the bits turned

on in both values:

00000000000000000111011111110111

Another way to accomplish that is using XOR (^)

to find bits that are on in only one value or the other:

E_ALL ^ E_NOTICE

error_reporting can also be used to demonstrate turning bits on.

The way to show just errors and recoverable errors is:

E_ERROR | E_RECOVERABLE_ERROR

This process combines E_ERROR

00000000000000000000000000000001

and

00000000000000000001000000000000

using the OR (|) operator

to get the bits turned on in either value:

00000000000000000001000000000001

Example #1 Bitwise AND, OR and XOR operations on integers

/*

* Ignore the top section,

* it is just formatting to make output clearer.

*/

$format = '(%1$2d = %1$04b) = (%2$2d = %2$04b)'

. ' %3$s (%4$2d = %4$04b)' . "\n";

echo <<

result value op test

--------- --------- -- ---------

EOH;

/*

* Here are the examples.

*/

$values = array(0, 1, 2, 4, 8);

$test = 1 + 4;

echo "\n Bitwise AND \n";

foreach ($values as $value) {

$result = $value & $test;

printf($format, $result, $value, '&', $test);

}

echo "\n Bitwise Inclusive OR \n";

foreach ($values as $value) {

$result = $value | $test;

printf($format, $result, $value, '|', $test);

}

echo "\n Bitwise Exclusive OR (XOR) \n";

foreach ($values as $value) {

$result = $value ^ $test;

printf($format, $result, $value, '^', $test);

}

?>

The above example will output:

--------- --------- -- ---------

result value op test

--------- --------- -- ---------

Bitwise AND

( 0 = 0000) = ( 0 = 0000) & ( 5 = 0101)

( 1 = 0001) = ( 1 = 0001) & ( 5 = 0101)

( 0 = 0000) = ( 2 = 0010) & ( 5 = 0101)

( 4 = 0100) = ( 4 = 0100) & ( 5 = 0101)

( 0 = 0000) = ( 8 = 1000) & ( 5 = 0101)

Bitwise Inclusive OR

( 5 = 0101) = ( 0 = 0000) | ( 5 = 0101)

( 5 = 0101) = ( 1 = 0001) | ( 5 = 0101)

( 7 = 0111) = ( 2 = 0010) | ( 5 = 0101)

( 5 = 0101) = ( 4 = 0100) | ( 5 = 0101)

(13 = 1101) = ( 8 = 1000) | ( 5 = 0101)

Bitwise Exclusive OR (XOR)

( 5 = 0101) = ( 0 = 0000) ^ ( 5 = 0101)

( 4 = 0100) = ( 1 = 0001) ^ ( 5 = 0101)

( 7 = 0111) = ( 2 = 0010) ^ ( 5 = 0101)

( 1 = 0001) = ( 4 = 0100) ^ ( 5 = 0101)

(13 = 1101) = ( 8 = 1000) ^ ( 5 = 0101)

Example #2 Bitwise XOR operations on strings

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

echo 2 ^ "3"; // Outputs 1

// 2 ^ ((int)"3") == 1

echo "2" ^ 3; // Outputs 1

// ((int)"2") ^ 3 == 1

?>

**Comparison Operators**

Comparison operators, as their name implies, allow you to compare two values. You may also be interested in viewing the type comparison tables, as they show examples of various type related comparisons.

Example | Name | Result |
---|---|---|

$a == $b | Equal |
if `TRUE` is equal to $a after type juggling.$b |

$a === $b | Identical |
if `TRUE` is equal to $a, and they are of the same type.$b |

$a != $b | Not equal |
if `TRUE` is not equal to $a after type juggling.$b |

$a <> $b | Not equal |
if `TRUE` is not equal to $a after type juggling.$b |

$a !== $b | Not identical |
if `TRUE` is not equal to $a, or they are not of the same type.$b |

$a < $b | Less than |
if `TRUE` is strictly less than $a.$b |

$a > $b | Greater than |
if `TRUE` is strictly greater than $a.$b |

$a <= $b | Less than or equal to |
if `TRUE` is less than or equal to $a.$b |

$a >= $b | Greater than or equal to |
if `TRUE` is greater than or equal to $a.$b |

If you compare a number with a string or the comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically. These rules also apply to the switch statement. The type conversion does not take place when the comparison is === or !== as this involves comparing the type as well as the value.

var_dump(0 == "a"); // 0 == 0 -> true

var_dump("1" == "01"); // 1 == 1 -> true

var_dump("10" == "1e1"); // 10 == 10 -> true

var_dump(100 == "1e2"); // 100 == 100 -> true

switch ("a") {

case 0:

echo "0";

break;

case "a": // never reached because "a" is already matched with 0

echo "a";

break;

}

?>

**Error Control Operators**

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.

If you have set a custom error handler function with set_error_handler() then it will still get called, but this custom error handler can (and should) call error_reporting() which will return 0 when the call that triggered the error was preceded by an @.

If the track_errors feature is enabled, any error message generated by the expression will be saved in the variable $php_errormsg. This variable will be overwritten on each error, so check early if you want to use it.

/* 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.

?>

**Execution Operators**

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 shell_exec().

$output = `ls -al`;

echo "

$output";

?>

**Incrementing/Decrementing Operators**

PHP supports C-style pre- and post-increment and decrement operators.

Note: The increment/decrement operators do not affect boolean values. Decrementing NULL values has no effect too, but incrementing them results in 1.

Example | Name | Effect |
---|---|---|

++$a | Pre-increment |
Increments by one, then returns $a.$a |

$a++ | Post-increment |
Returns , then increments $a by one.$a |

--$a | Pre-decrement |
Decrements by one, then returns $a.$a |

$a-- | Post-decrement |
Returns , then decrements $a by one.$a |

**Logical Operators**

Example | Name | Result |
---|---|---|

$a and $b | And |
if both `TRUE` and $a are $b.`TRUE` |

$a or $b | Or |
if either `TRUE` or $a is $b.`TRUE` |

$a xor $b | Xor |
if either `TRUE` or $a is $b, but not both.`TRUE` |

! $a | Not |
if `TRUE` is not $a.`TRUE` |

$a && $b | And |
if both `TRUE` and $a are $b.`TRUE` |

$a || $b | Or |
if either `TRUE` or $a is $b.`TRUE` |

The reason for the two different variations of "and" and "or" operators is that they operate at different precedences.

**String Operators**

There are two string 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 Assignment Operators for more information.

$a = "Hello ";

$b = $a . "World!"; // now $b contains "Hello World!"

$a = "Hello ";

$a .= "World!"; // now $a contains "Hello World!"

?>

**Array Operators**

Example | Name | Result |
---|---|---|

$a + $b | Union |
Union of and $a.$b |

$a == $b | Equality |
if `TRUE` and $a have the same key/value pairs.$b |

$a === $b | Identity |
if `TRUE` and $a have the same key/value pairs in the same order and of the same types.$b |

$a != $b | Inequality |
if `TRUE` is not equal to $a.$b |

$a <> $b | Inequality |
if `TRUE` is not equal to $a.$b |

$a !== $b | Non-identity |
if `TRUE` is not identical to $a.$b |

The + operator returns the right-hand array appended to the left-hand array; for keys that exist in both arrays, the elements from the left-hand array will be used, and the matching elements from the right-hand array will be ignored.

**Type Operators**

instanceof is used to determine whether a PHP variable is an instantiated object of a certain class:

Example #1 Using instanceof with classes

class MyClass

{

}

class NotMyClass

{

}

$a = new MyClass;

var_dump($a instanceof MyClass);

var_dump($a instanceof NotMyClass);

?>

The above example will output:

bool(true)

bool(false)

instanceof can also be used to determine whether a variable is an instantiated object of a class that inherits from a parent class