Operators are the symbols that do the work in an expression: they add numbers, compare values, join strings and make decisions possible. You have already met = and the dot . in earlier lessons. Here you will learn the full everyday set of PHP operators, with special attention to comparisons, because choosing the wrong comparison operator is a classic source of PHP bugs.
Arithmetic operators
| Operator | Meaning | Example | Result |
|---|---|---|---|
+ | Addition | 7 + 3 | 10 |
- | Subtraction | 7 - 3 | 4 |
* | Multiplication | 7 * 3 | 21 |
/ | Division | 7 / 2 | 3.5 |
% | Remainder (modulo) | 7 % 3 | 1 |
** | Power | 2 ** 10 | 1024 |
Division with / returns a float when the result is not a whole number. If you want whole-number division, use the function intdiv(7, 2), which returns 3. Dividing by zero throws a DivisionByZeroError, so check the divisor first when it comes from user input.
Assignment operators
= stores a value. The combined operators update a variable in place: $total += 50 is short for $total = $total + 50. The same pattern works with -=, *=, /=, %=, **= and the string version .=. The increment ++ and decrement -- operators add or subtract 1, which you will use constantly in loops.
<?php
$ticketPrice = 250;
$tickets = 4;
$total = $ticketPrice * $tickets;
echo "Subtotal: $total\n";
$total -= 100; // discount coupon
echo "After coupon: $total\n";
echo "Per person: ", $total / $tickets, "\n";
echo "Full rows of 3 seats: ", intdiv($tickets, 3), "\n";
echo "Seats left over: ", $tickets % 3, "\n";
$tickets++;
echo "Tickets now: $tickets";Subtotal: 1000 After coupon: 900 Per person: 225 Full rows of 3 seats: 1 Seats left over: 1 Tickets now: 5
PHP operators and precedence
When an expression mixes operators, PHP follows precedence rules, just like school maths: ** first, then *, / and %, then + and -. So 2 + 3 * 4 is 14, not 20. Do not try to memorise the full precedence table. Add brackets whenever the order is not obvious: (2 + 3) * 4 is clear to both PHP and the next person who reads your code.
Comparison operators
Comparisons return true or false. PHP has two kinds of equality, and the difference is important:
==(loose equality) converts the values to a common type first, then compares.===(strict equality) istrueonly when the values are equal and of the same type.
The same applies to “not equal”: != is loose and !== is strict. Loose comparison can produce results that look wrong, so the safe habit is to use === and !== by default and convert values yourself when needed.
<?php
var_dump("1" == "01"); // both look numeric, compared as numbers
var_dump("1" === "01"); // different strings
var_dump(100 == "1e2"); // "1e2" is 100 in scientific notation
var_dump(null == false);
var_dump(null === false);
var_dump(5 <=> 9); // spaceship: -1, 0 or 1bool(true) bool(false) bool(true) bool(true) bool(false) int(-1)
The other comparison operators work as you would expect: <, >, <= and >=. The spaceship operator <=> returns -1 if the left side is smaller, 0 if both are equal and 1 if the left is larger. It is mainly used when sorting arrays.
Tip: PHP 8 fixed one famous trap: 0 == "abc" used to be true in PHP 7, but is false in PHP 8. Even so, other loose comparisons still surprise people, so stick with ===.
Logical operators
| Operator | True when… |
|---|---|
$a && $b | both are true |
$a || $b | at least one is true |
!$a | $a is false |
$a xor $b | exactly one is true |
PHP evaluates && and || lazily: if the left side already decides the answer, the right side is not run. That lets you write checks such as $count !== 0 && $total / $count > 100 without risking a division by zero.
Watch out: PHP also has the words and and or, but they have lower precedence than =. $ok = true and false; stores true. Use && and || to avoid this surprise.
Null coalescing, ternary and nullsafe operators
These three operators make code shorter and safer when a value might be missing:
- Ternary
condition ? a : bpicks one of two values. Keep it for simple choices; nested ternaries without brackets are not allowed in PHP 8. - Null coalescing
$x ?? 'default'returns$xif it exists and is notnull, otherwise the default. It never produces an “undefined” warning, which makes it perfect for optional form fields.$x ??= 'default'assigns the default only when needed. - Nullsafe
$object?->propertyreads a property or calls a method only if the object is notnull; otherwise the whole expression becomesnull.
<?php
$marks = 72;
echo $marks >= 40 ? "Pass" : "Fail", "\n";
$settings = ['theme' => 'dark'];
echo $settings['language'] ?? 'English', "\n";
$settings['fontSize'] ??= 16;
echo "Font size: {$settings['fontSize']}\n";
$customer = null; // nobody is logged in
echo $customer?->name ?? 'Guest';Pass English Font size: 16 Guest
The last line combines both ideas: ?-> turns a missing customer into null, and ?? replaces that null with “Guest”. You will use these PHP operators heavily in the next lesson, PHP Conditions, and when reading form data.
