Lesson 5 of 12

PHP Operators

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

OperatorMeaningExampleResult
+Addition7 + 310
-Subtraction7 - 34
*Multiplication7 * 321
/Division7 / 23.5
%Remainder (modulo)7 % 31
**Power2 ** 101024

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";
Output
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) is true only 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 1
Output
bool(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

OperatorTrue when…
$a && $bboth are true
$a || $bat least one is true
!$a$a is false
$a xor $bexactly 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 : b picks one of two values. Keep it for simple choices; nested ternaries without brackets are not allowed in PHP 8.
  • Null coalescing $x ?? 'default' returns $x if it exists and is not null, 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?->property reads a property or calls a method only if the object is not null; otherwise the whole expression becomes null.
<?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';
Output
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.

Further reading

Key takeaways

  • Arithmetic: + - * / % **; use intdiv() for whole-number division.
  • Combined assignment (+=, .= and so on) updates a variable in place.
  • Prefer strict === and !==; loose == converts types first.
  • Use &&, || and ! rather than and/or.
  • ?? supplies a default for missing or null values; ?-> safely reads from an object that may be null.

Quick quiz

Check what you learned – pick an answer.

1. What does var_dump("5" === 5); print?

2. What does echo $_GET['page'] ?? 1; print when there is no page parameter?

3. What is the result of 17 % 5?

Practice exercise

A shop gives free delivery on orders of Rs. 500 or more. Given $cart = 420; and an optional $coupon that may be null, compute the final amount: subtract the coupon value (treat a missing coupon as 0), then add Rs. 40 delivery if the amount is below 500. Print the final amount.

Show a hint

Use ?? for the coupon and a ternary for the delivery charge.

Show the solution
<?php
$cart = 420;
$coupon = null;

$amount = $cart - ($coupon ?? 0);
$delivery = $amount >= 500 ? 0 : 40;

echo "Final amount: " . ($amount + $delivery); // Final amount: 460

Progress is saved in this browser only.