Operators are fundamental components in PHP programming, facilitating everything from basic arithmetic to complex logical operations. Understanding PHP operators is crucial for writing efficient, readable, and error-free code. This comprehensive guide breaks down all types of PHP operators, their usage, and best practices to help you build better PHP applications.
What are PHP Operators?
PHP operators are symbols that tell the interpreter to perform specific mathematical, relational, or logical operations. They take one or more values (operands) and yield another value (often, but not always, of the same type).
Arithmetic Operators
Arithmetic operators perform basic mathematical operations.
Operator | Name | Example | Result |
---|---|---|---|
+ | Addition | $a + $b | Sum of $a and $b |
– | Subtraction | $a – $b | Difference of $a and $b |
* | Multiplication | $a * $b | Product of $a and $b |
/ | Division | $a / $b | Quotient of $a and $b |
% | Modulus | $a % $b | Remainder of $a divided by $b |
** | Exponentiation | $a ** $b | Result of raising $a to the power of $b |
<?php $a = 10; $b = 3; echo $a + $b; // Outputs: 13 echo $a - $b; // Outputs: 7 echo $a * $b; // Outputs: 30 echo $a / $b; // Outputs: 3.3333333333333 echo $a % $b; // Outputs: 1 echo $a ** $b; // Outputs: 1000 ?>
Division by Zero
Be cautious with division operations. PHP handles division by zero differently based on the PHP version:
<?php // In modern PHP versions $result = 5 / 0; // Generates a Warning: Division by zero // $result will be set to INF (infinity) // Always check before division $divisor = 0; if ($divisor != 0) { $result = 10 / $divisor; } else { $result = 'Cannot divide by zero'; } ?>
Assignment Operators
Assignment operators are used to write values to variables.
Operator | Example | Equivalent To |
---|---|---|
= | $a = $b | $a = $b |
+= | $a += $b | $a = $a + $b |
-= | $a -= $b | $a = $a – $b |
*= | $a *= $b | $a = $a * $b |
/= | $a /= $b | $a = $a / $b |
%= | $a %= $b | $a = $a % $b |
**= | $a **= $b | $a = $a ** $b |
<?php $num = 10; $num += 5; // $num is now 15 $num -= 3; // $num is now 12 $num *= 2; // $num is now 24 $num /= 4; // $num is now 6 $num %= 4; // $num is now 2 $num **= 3; // $num is now 8 (2^3) ?>
String Operators
PHP has two operators specifically designed for strings.
Operator | Name | Example | Result |
---|---|---|---|
. | Concatenation | $a . $b | Concatenation of $a and $b |
.= | Concatenation assignment | $a .= $b | Appends $b to $a |
<?php $greeting = "Hello"; $name = "World"; // Concatenation $message = $greeting . " " . $name; echo $message; // Outputs: Hello World // Concatenation assignment $greeting .= " beautiful " . $name; echo $greeting; // Outputs: Hello beautiful World ?>
Comparison Operators
Comparison operators compare two values and return a boolean result.
Operator | Name | Example | Result |
---|---|---|---|
== | Equal | $a == $b | True if $a is equal to $b after type juggling |
=== | Identical | $a === $b | True if $a is equal to $b, and they are of the same type |
!= | Not equal | $a != $b | True if $a is not equal to $b after type juggling |
<> | Not equal | $a <> $b | Same as != |
!== | Not identical | $a !== $b | True if $a is not equal to $b, or they are not of the same type |
< | Less than | $a < $b | True if $a is strictly less than $b |
> | Greater than | $a > $b | True if $a is strictly greater than $b |
<= | Less than or equal to | $a <= $b | True if $a is less than or equal to $b |
>= | Greater than or equal to | $a >= $b | True if $a is greater than or equal to $b |
<=> | Spaceship | $a <=> $b | Returns -1, 0, or 1 when $a is less than, equal to, or greater than $b |
<?php $a = 5; $b = "5"; $c = 10; // Equal vs Identical var_dump($a == $b); // Outputs: bool(true) - values are equal var_dump($a === $b); // Outputs: bool(false) - types are different // Not equal vs Not identical var_dump($a != $c); // Outputs: bool(true) var_dump($a !== $c); // Outputs: bool(true) // Less than, Greater than var_dump($a < $c); // Outputs: bool(true) var_dump($a > $c); // Outputs: bool(false) // Spaceship operator (PHP 7+) var_dump($a <=> $c); // Outputs: int(-1) because $a < $c var_dump($c <=> $a); // Outputs: int(1) because $c > $a var_dump($a <=> $a); // Outputs: int(0) because $a = $a ?>
Common Pitfalls with Comparison Operators
Be careful with loose comparisons:
<?php // Loose comparison can lead to unexpected results var_dump(0 == "0"); // bool(true) var_dump(0 == ""); // bool(true) var_dump(0 == false); // bool(true) var_dump("0" == false); // bool(true) // Always use strict comparison (===) when type matters var_dump(0 === "0"); // bool(false) var_dump(0 === ""); // bool(false) var_dump(0 === false); // bool(false) var_dump("0" === false); // bool(false) ?>
Increment/Decrement Operators
These operators increase or decrease a variable’s value by one.
Operator | Name | Description |
---|---|---|
++$a | Pre-increment | Increments $a by one, then returns $a |
$a++ | Post-increment | Returns $a, then increments $a by one |
–$a | Pre-decrement | Decrements $a by one, then returns $a |
$a– | Post-decrement | Returns $a, then decrements $a by one |
<?php $a = 5; $b = 5; // Pre-increment vs Post-increment $result1 = ++$a; // $a is incremented to 6, then $result1 is assigned 6 $result2 = $b++; // $result2 is assigned 5, then $b is incremented to 6 echo "a: $a, result1: $result1<br>"; // Outputs: a: 6, result1: 6 echo "b: $b, result2: $result2<br>"; // Outputs: b: 6, result2: 5 // Pre-decrement vs Post-decrement $c = 10; $d = 10; $result3 = --$c; // $c is decremented to 9, then $result3 is assigned 9 $result4 = $d--; // $result4 is assigned 10, then $d is decremented to 9 echo "c: $c, result3: $result3<br>"; // Outputs: c: 9, result3: 9 echo "d: $d, result4: $result4<br>"; // Outputs: d: 9, result4: 10 ?>
Logical Operators
Logical operators combine conditional statements.
Operator | Name | Example | Result |
---|---|---|---|
and | And | $a and $b | True if both $a and $b are true |
or | Or | $a or $b | True if either $a or $b is true |
xor | Xor | $a xor $b | True if either $a or $b is true, but not both |
&& | And | $a && $b | True if both $a and $b are true |
|| | Or | $a || $b | True if either $a or $b is true |
! | Not | !$a | True if $a is not true |
<?php $is_user = true; $is_admin = false; // AND operators if ($is_user && $is_admin) { echo "User is an admin"; } else { echo "User is not an admin"; // This will execute } // OR operators if ($is_user || $is_admin) { echo "Either a user or an admin"; // This will execute } // XOR (exclusive OR) if ($is_user xor $is_admin) { echo "Either a user or an admin, but not both"; // This will execute } // NOT operator if (!$is_admin) { echo "Not an admin"; // This will execute } ?>
Operator Precedence and Short-Circuit Evaluation
PHP logical operators evaluate from left to right and stop as soon as the result is determined (short-circuit evaluation):
<?php // Short-circuit evaluation with && $a = false; $b = someExpensiveFunction(); // Never called because $a is false and using && // Short-circuit evaluation with || $c = true; $d = someExpensiveFunction(); // Never called because $c is true and using || // Operator precedence: && has higher precedence than || $result = $a && $b || $c && $d; // Equivalent to: ($a && $b) || ($c && $d) ?>
Differences Between and
/or
and &&
/||
The and
/or
operators have lower precedence than the &&
/||
operators:
<?php // Different precedence can lead to unexpected results $e = false || true; // $e is true because || has higher precedence than = $f = false or true; // $f is false because = has higher precedence than or var_dump($e); // bool(true) var_dump($f); // bool(false) ?>
Bitwise Operators
Bitwise operators manipulate individual bits within integers.
Operator | Name | Example | Result |
---|---|---|---|
& | And | $a & $b | Bits that are set in both $a and $b |
| | Or | $a | $b | Bits that are set in either $a or $b |
^ | Xor | $a ^ $b | Bits that are set in $a or $b but not both |
~ | Not | ~$a | Bits that are set in $a are not set, and vice versa |
<< | Shift left | $a << $b | Shift the bits of $a $b steps to the left (multiply by 2^$b) |
>> | Shift right | $a >> $b | Shift the bits of $a $b steps to the right (divide by 2^$b) |
<?php $a = 5; // Binary: 0101 $b = 3; // Binary: 0011 echo $a & $b; // Outputs: 1 (Binary: 0001) echo $a | $b; // Outputs: 7 (Binary: 0111) echo $a ^ $b; // Outputs: 6 (Binary: 0110) echo ~$a; // Outputs: -6 (depends on int size) echo $a << 1; // Outputs: 10 (Binary: 1010) echo $a >> 1; // Outputs: 2 (Binary: 0010) ?>
Practical Uses of Bitwise Operators
Bitwise operators are commonly used for:
- Flag handling: When you need to store multiple boolean values efficiently.
<?php // Define permissions using bit flags define('READ', 1); // 001 in binary define('WRITE', 2); // 010 in binary define('EXECUTE', 4); // 100 in binary // Assign permissions $userPermissions = READ | WRITE; // 3 (011 in binary) // Check if user has specific permission function hasPermission($permissions, $flag) { return ($permissions & $flag) === $flag; } echo hasPermission($userPermissions, READ) ? 'Can read' : 'Cannot read'; // Outputs: Can read echo hasPermission($userPermissions, WRITE) ? 'Can write' : 'Cannot write'; // Outputs: Can write echo hasPermission($userPermissions, EXECUTE) ? 'Can execute' : 'Cannot execute'; // Outputs: Cannot execute // Add permission $userPermissions |= EXECUTE; // Now has all permissions (7, 111 in binary) // Remove permission $userPermissions &= ~WRITE; // Remove write permission (5, 101 in binary) // Toggle permission $userPermissions ^= READ; // Toggle read permission (4, 100 in binary - READ is now off) ?>
- Memory-efficient storage: When working with limited resources.
<?php // Store 8 boolean values in a single byte $byte = 0; $positions = [0, 2, 4, 7]; // Positions to set to true foreach ($positions as $pos) { $byte |= (1 << $pos); } // Check if a specific position is set function isBitSet($byte, $position) { return ($byte & (1 << $position)) !== 0; } for ($i = 0; $i < 8; $i++) { echo "Position $i is " . (isBitSet($byte, $i) ? 'set' : 'not set') . "<br>"; } ?>
Array Operators
Array operators perform operations on arrays.
Operator | Name | Example | Result |
---|---|---|---|
+ | Union | $a + $b | Union of $a and $b |
== | Equality | $a == $b | True if $a and $b have the same key/value pairs |
=== | Identity | $a === $b | True if $a and $b have the same key/value pairs in the same order and of the same types |
!= | Inequality | $a != $b | True if $a is not equal to $b |
<> | Inequality | $a <> $b | True if $a is not equal to $b |
!== | Non-identity | $a !== $b | True if $a is not identical to $b |
<?php $array1 = ["a" => "apple", "b" => "banana"]; $array2 = ["b" => "berry", "c" => "cherry"]; $array3 = ["b" => "banana", "a" => "apple"]; // Array union $result = $array1 + $array2; print_r($result); // Outputs: Array ( [a] => apple [b] => banana [c] => cherry ) // Note that $array1's 'b' is kept, not overwritten // Array equality (==) vs. identity (===) var_dump($array1 == $array3); // bool(true) - same pairs, different order var_dump($array1 === $array3); // bool(false) - same pairs but different order // Array inequality var_dump($array1 != $array2); // bool(true) var_dump($array1 !== $array2); // bool(true) ?>
The Union Operator vs. array_merge()
The union operator (+
) and array_merge()
function behave differently with arrays:
<?php $array1 = ["a" => "apple", "b" => "banana"]; $array2 = ["b" => "berry", "c" => "cherry"]; // Union operator keeps the original keys and doesn't overwrite existing keys $result1 = $array1 + $array2; print_r($result1); // Outputs: Array ( [a] => apple [b] => banana [c] => cherry ) // array_merge() appends numeric keys and overwrites string keys $result2 = array_merge($array1, $array2); print_r($result2); // Outputs: Array ( [a] => apple [b] => berry [c] => cherry ) // With numeric keys: $numArray1 = [1, 2, 3]; $numArray2 = [4, 5, 6]; $numResult1 = $numArray1 + $numArray2; print_r($numResult1); // Outputs: Array ( [0] => 1 [1] => 2 [2] => 3 ) // $numArray2's values aren't used because the keys already exist $numResult2 = array_merge($numArray1, $numArray2); print_r($numResult2); // Outputs: Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 ) ?>
Ternary Operator
The ternary operator is a shorthand for the if-else statement.
<?php // Syntax: condition ? value_if_true : value_if_false $age = 20; $status = ($age >= 18) ? 'adult' : 'minor'; echo $status; // Outputs: adult // Nested ternary operations (use with caution) $age = 15; $status = ($age >= 21) ? 'adult' : (($age >= 13) ? 'teenager' : 'child'); echo $status; // Outputs: teenager // Short ternary operator (PHP 5.3+) $user = null; $name = $user ?: 'Guest'; // Equivalent to: $name = $user ? $user : 'Guest' echo $name; // Outputs: Guest ?>
Null Coalescing Operator (PHP 7+)
The null coalescing operator (??
) is a shorthand for the common case of using a ternary with isset()
:
<?php // Syntax: $value = $possiblyNull ?? $fallbackValue // Without null coalescing $username = isset($_GET['user']) ? $_GET['user'] : 'nobody'; // With null coalescing $username = $_GET['user'] ?? 'nobody'; // Chaining multiple null coalescing operators $username = $_GET['user'] ?? $_POST['user'] ?? $_COOKIE['user'] ?? 'nobody'; ?>
Nullsafe Operator (PHP 8+)
The nullsafe operator (?->
) allows you to access properties and methods on objects that might be null without causing errors:
<?php // Without nullsafe operator $country = null; if ($user !== null) { if ($user->getAddress() !== null) { $country = $user->getAddress()->getCountry(); } } // With nullsafe operator $country = $user?->getAddress()?->getCountry(); // Can be combined with null coalescing $country = $user?->getAddress()?->getCountry() ?? 'Unknown'; ?>
Error Control Operator
The error control operator (@
) suppresses error messages from the expression it prefixes:
<?php // Without error control $file = file_get_contents('non_existent_file.txt'); // Generates a warning // With error control $file = @file_get_contents('non_existent_file.txt'); // No warning displayed // Better practice: use try-catch instead try { if (!file_exists('non_existent_file.txt')) { throw new Exception('File not found'); } $file = file_get_contents('non_existent_file.txt'); } catch (Exception $e) { echo $e->getMessage(); } ?>
Warning: The error control operator (
@
) should be used sparingly. It can make debugging difficult as it hides errors that could indicate serious problems.
Execution Operator
The execution operator (backticks `) executes the command in the backticks as a shell command and returns the output:
<?php // Execute a command and get the output $output = `ls -la`; echo $output; // A safer alternative is the exec() function $output = []; exec('ls -la', $output); print_r($output); ?>
Warning: Always sanitize any variables used in shell commands to prevent command injection attacks. Better yet, avoid using shell commands when PHP alternatives exist.
Type Operators
PHP provides type operators for working with classes and objects:
Operator | Name | Description |
---|---|---|
instanceof | Type checking | Checks if an object is an instance of a specific class |
<?php class ParentClass {} class ChildClass extends ParentClass {} class UnrelatedClass {} $obj = new ChildClass(); var_dump($obj instanceof ChildClass); // bool(true) var_dump($obj instanceof ParentClass); // bool(true) var_dump($obj instanceof UnrelatedClass); // bool(false) // Can also check interfaces and abstract classes var_dump($obj instanceof stdClass); // bool(false) var_dump($obj instanceof Traversable); // bool(false) // With string class names $className = 'ChildClass'; var_dump($obj instanceof $className); // bool(true) ?>
Operator Precedence
Operators have different precedence levels that determine the order of operations:
Precedence | Operator(s) | Description |
---|---|---|
Highest | ++ — | Increment/decrement |
~ – (int) (float) (string) (array) (object) (bool) ! | Type casting and bitwise NOT | |
** | Exponentiation | |
* / % | Multiplication, division, modulus | |
+ – . | Addition, subtraction, string concatenation | |
<< >> | Bitwise shift | |
< <= > >= | Comparison | |
== != === !== <> <=> | Equality | |
& | Bitwise AND | |
^ | Bitwise XOR | |
| | Bitwise OR | |
&& | Logical AND | |
|| | Logical OR | |
?? | Null coalescing | |
?: | Ternary | |
= += -= *= /= .= %= &= |= ^= <<= >>= **= | Assignment | |
Lowest | and | Logical AND |
xor | Logical XOR | |
or | Logical OR |
<?php // Expression: 5 + 3 * 2 echo 5 + 3 * 2; // Outputs: 11 (multiplication happens first) // Expression: (5 + 3) * 2 echo (5 + 3) * 2; // Outputs: 16 (parentheses override precedence) // Complex expression $result = 10 + 5 * 3 - 2 / 2 ** 3; // Equivalent to: 10 + (5 * 3) - (2 / (2 ** 3)) // Equivalent to: 10 + 15 - (2 / 8) // Equivalent to: 10 + 15 - 0.25 // Equivalent to: 24.75 echo $result; // Outputs: 24.75 ?>
Frequently Asked Questions (FAQ)
What’s the difference between ==
and ===
in PHP?
<?php $a = 5; $b = "5"; // == compares values after type juggling var_dump($a == $b); // bool(true) // === compares values AND types var_dump($a === $b); // bool(false) // Best practice: Use === unless you specifically need type juggling ?>
Why should I avoid the error control operator (@
)?
The error control operator suppresses error messages which can make debugging difficult:
<?php // Problem: Error is suppressed, but operation still fails $file = @file_get_contents('missing_file.txt'); // No warning shown var_dump($file); // bool(false) // Better approach: if (file_exists('missing_file.txt')) { $file = file_get_contents('missing_file.txt'); } else { // Handle the error properly error_log('File missing: missing_file.txt'); $file = null; } ?>
When should I use the spaceship operator (<=>
)?
The spaceship operator is useful for sorting and comparison functions:
<?php // Custom sorting function function customSort($a, $b) { return $a <=> $b; } $numbers = [5, 2, 9, 1, 7]; usort($numbers, 'customSort'); print_r($numbers); // Outputs: Array ( [0] => 1 [1] => 2 [2] => 5 [3] => 7 [4] => 9 ) // For complex objects class Product { public $name; public $price; public function __construct($name, $price) { $this->name = $name; $this->price = $price; } } $products = [ new Product("Laptop", 1200), new Product("Phone", 800), new Product("Tablet", 500) ]; // Sort by price usort($products, function($a, $b) { return $a->price <=> $b->price; }); // Print sorted products foreach ($products as $product) { echo "{$product->name}: \${$product->price}<br>"; } // Outputs: // Tablet: $500 // Phone: $800 // Laptop: $1200 ?>
What’s the difference between ||
and or
operators?
They differ in operator precedence:
<?php // || has higher precedence than assignment (=) $a = false || true; // Evaluates to: $a = (false || true) = true var_dump($a); // bool(true) // or has lower precedence than assignment (=) $b = false or true; // Evaluates to: ($b = false) or true var_dump($b); // bool(false) // Best practice: Use || and && for most logical operations // Use or and and only when their lower precedence is needed ?>
How can I safely use bitwise operators with large numbers?
PHP’s integer size is platform-dependent, which can affect bitwise operations:
<?php // Check integer size echo PHP_INT_SIZE; // Usually 4 (32-bit) or 8 (64-bit) // On 32-bit systems, be careful with shifts that exceed 31 bits $a = 1 << 31; // Might result in a negative number on 32-bit systems echo $a; // Outputs: -2147483648 on 32-bit, 2147483648 on 64-bit // For portable code: function safeShiftLeft($a, $b) { // For large shifts, use multiplication instead if ($b >= PHP_INT_SIZE * 8 - 1) { return 0; // Shifted too far } return $a << $b; } ?>
What’s the difference between the ternary operator and null coalescing operator?
<?php // Ternary checks if condition is true $result1 = $condition ? $valueIfTrue : $valueIfFalse; // Null coalescing checks if variable exists and isn't null $result2 = $possiblyNullOrUndefined ?? $fallbackValue; // Example $user = ['name' => 'John', 'age' => null]; // Ternary: checks if age is truthy (non-null and non-zero) $age1 = $user['age'] ? $user['age'] : 'Unknown'; // 'Unknown' (null is falsy) // Null coalescing: checks if age is set and not null $age2 = $user['age'] ?? 'Unknown'; // 'Unknown' (null triggers fallback) // If age was 0 instead of null: $user['age'] = 0; $age1 = $user['age'] ? $user['age'] : 'Unknown'; // 'Unknown' (0 is falsy) $age2 = $user['age'] ?? 'Unknown'; // 0 (0 is not null) ?>
Best Practices for PHP Operators
- Use strict comparisons: Always use
===
and!==
unless you specifically need type juggling. - Be careful with short-circuit evaluation: Understand that
&&
and||
operators evaluate expressions from left to right and stop as soon as the result is determined. - Be explicit with operator precedence: Use parentheses to clarify the order of operations, especially with complex expressions.
- Avoid the error control operator (
@
): Instead, use proper error handling with conditionals or try-catch blocks. - Use the null coalescing operator (
??
) instead of isset() with ternary: It’s more concise and readable. - Be cautious with increment/decrement operators: Especially when used within expressions, as they can make code harder to understand.
- Choose the right string concatenation approach: For simple concatenations, use the concatenation operator (
.
). For complex ones, consider using sprintf() or string interpolation.
<?php // Concatenation for simple strings $fullName = $firstName . ' ' . $lastName; // String interpolation for more complex strings $message = "Hello $firstName $lastName, welcome back!"; // sprintf for formatted output $formattedPrice = sprintf("Price: $%.2f", $price); ?>
Conclusion
PHP operators are the building blocks that enable you to create complex logic in your applications. Understanding how each operator works, their precedence, and best practices for their use will help you write cleaner, more efficient, and error-free PHP code.
From basic arithmetic to advanced logical operations, mastering PHP operators is fundamental to becoming a proficient PHP developer. By following the examples and recommendations in this guide, you’ll be better equipped to leverage PHP’s powerful operator system in your projects.