Arithmetic Operators
| Operator | Name | Example | Result |
|---|---|---|---|
+ | Addition | 5 + 3 | 8 |
- | Subtraction | 5 - 3 | 2 |
* | Multiplication | 5 * 3 | 15 |
/ | Division | 10 / 4 | 2.5 |
% | Modulus | 10 % 3 | 1 |
** | Exponentiation | 2 ** 10 | 1024 |
intdiv() | Integer division | intdiv(10, 3) | 3 |
Assignment Operators
<?php
$x = 10; // assign
$x += 5; // $x = $x + 5 -> 15
$x -= 3; // 12
$x *= 2; // 24
$x /= 4; // 6
$x %= 4; // 2
$x **= 3; // 8
$s = "Hello";
$s .= " World"; // string concatenation -> "Hello World"
$a = ["a"];
$a += ["b", "c"]; // array union (keeps existing keys)
// Null coalescing assignment (PHP 7.4+)
$opts["timeout"] ??= 30; // only sets if currently null/missing
Comparison Operators
| Operator | Name | Notes |
|---|---|---|
== | Equal (loose) | Type juggles - avoid |
=== | Identical (strict) | Type AND value match - prefer this |
!= or <> | Not equal (loose) | Avoid |
!== | Not identical (strict) | Prefer this |
< <= > >= | Less/greater than | Works on numbers and strings |
<=> | Spaceship | -1, 0, or 1 - perfect for sorting |
<?php
var_dump(5 == "5"); // true (loose)
var_dump(5 === "5"); // false (types differ)
var_dump(0 == ""); // PHP 7: true, PHP 8: false
var_dump(null == false); // true (loose)
var_dump(null === false);// false
Logical Operators
| Operator | Result |
|---|---|
$a && $b | true if both true |
$a || $b | true if either true |
!$a | true if $a is false |
$a xor $b | true if exactly one is true |
$a and $b | Same as && but lower precedence (avoid) |
$a or $b | Same as || but lower precedence (avoid) |
The word forms and and or have lower precedence than =. $x = true and false assigns true (then ignores the and false). Use && / || always.
String Operators
<?php
$a = "Hello";
$b = "World";
// . concatenation
echo $a . " " . $b; // Hello World
// .= concat-assign
$a .= "!"; // $a is now "Hello!"
// Interpolation (double quotes only)
echo "Greeting: $a";
// Heredoc - alternative for big strings
$html = <<<HTML
<p>$a $b</p>
HTML;
Increment / Decrement
<?php
$n = 5;
echo ++$n; // 6 (pre-increment: bump, then return)
echo $n++; // 6 (post-increment: return, then bump) - now $n is 7
echo --$n; // 6
echo $n--; // 6 - now $n is 5
// Works on letters too
$char = "a";
$char++; // "b"
$char = "z";
$char++; // "aa"
Ternary & Null Coalescing
<?php
// Standard ternary
$age = 17;
$type = $age >= 18 ? "Adult" : "Minor";
// Short ternary (Elvis) - returns left if truthy, else right
$name = $input ?: "Anonymous"; // ?: instead of ? $input :
// Null coalescing ?? (PHP 7.0+)
$lang = $_GET["lang"] ?? "en"; // no warning if key missing
// Chained
$value = $a ?? $b ?? $c ?? "default";
// Null coalescing assignment ??= (PHP 7.4+)
$config["debug"] ??= false; // sets only if null/missing
Spaceship Operator <=>
Returns -1, 0, or 1 depending on whether the left is less than, equal to, or greater than the right. Designed for usort().
<?php
echo 1 <=> 2; // -1
echo 1 <=> 1; // 0
echo 2 <=> 1; // 1
// Sort an array of users by age
$users = [["age" => 30], ["age" => 22], ["age" => 45]];
usort($users, fn($a, $b) => $a["age"] <=> $b["age"]);
// Result: 22, 30, 45
// Multi-key sort
usort($users, fn($a, $b) =>
[$a["lastName"], $a["firstName"]]
<=>
[$b["lastName"], $b["firstName"]]
);
Nullsafe ?-> (PHP 8.0+)
Chain method/property calls without crashing if any link is null:
<?php
// Old way - verbose
$country = null;
if ($user !== null) {
$address = $user->getAddress();
if ($address !== null) {
$country = $address->getCountry();
}
}
// New way (PHP 8.0+)
$country = $user?->getAddress()?->getCountry();
// Short-circuits to null at first null link
Bitwise Operators
| Operator | Name |
|---|---|
& | AND |
| | OR |
^ | XOR |
~ | NOT |
<< | Left shift |
>> | Right shift |
<?php
// Permission flags (classic bitmask pattern)
const READ = 1; // 0001
const WRITE = 2; // 0010
const DELETE = 4; // 0100
$perms = READ | WRITE; // 0011 = 3
// Check a flag
if ($perms & WRITE) echo "Can write";
// Remove a flag
$perms &= ~WRITE; // 0001
Operator Precedence
Some operators bind tighter than others. Add parentheses whenever you're unsure - they cost nothing and make intent obvious.
<?php
// Without parens - relies on precedence
$result = 2 + 3 * 4; // 14, not 20
// With parens - intent obvious
$result = ($price * $quantity) + $tax;
// Common gotcha: assignment vs comparison
if (($user = findUser($id)) !== null) {
// ok - explicit
}
The full precedence table is in the PHP manual - but you rarely need to memorize it if you use parentheses.