Operators and expressions

Do maths, compare values, combine conditions, and provide sensible defaults.

  • Beginner
  • 4 min read
  • Updated 17 Oct 2026

What you will learn

  • Use arithmetic and assignment operators
  • Compare values with == and ===, and know the difference
  • Combine conditions with &&, || and !
  • Provide defaults with ?? and choose values with the ternary operator

Before you start

An expression is anything that produces a value: 5, $price, $price * 2. Operators combine values into new values. You already used one: = assigns.

Arithmetic

OperatorMeaningExampleResult
+Add7 + 29
-Subtract7 - 25
*Multiply7 * 214
/Divide7 / 23.5
%Remainder (modulo)7 % 21
**Power7 ** 249
PHP
<?php

$items = 17;
$perBox = 5;

$fullBoxes = intdiv($items, $perBox); // 3
$leftOver = $items % $perBox;         // 2

echo "{$fullBoxes} full boxes, {$leftOver} left over";

intdiv() does whole-number division. % is handy for "every nth item" tasks, such as alternating row colours: $i % 2 === 0 is true for even numbers.

Dividing by zero throws a DivisionByZeroError in PHP 8. Check the divisor first when it comes from user input.

Normal maths precedence applies: * and / happen before + and -. Use brackets to make intent clear: ($a + $b) * $c.

Assignment shortcuts

PHP
<?php

$total = 10;
$total += 5;   // same as $total = $total + 5;  -> 15
$total -= 3;   // 12
$total *= 2;   // 24
$total /= 4;   // 6

$count = 0;
$count++;      // add 1 -> 1

$message = 'Hello';
$message .= ' world'; // append -> 'Hello world'

Comparison

Comparisons produce true or false.

OperatorTrue when
===Equal and the same type
!==Not equal, or different types
==Equal after type conversion
!=Not equal after type conversion
< > <= >=Less than, greater than, and so on
<=>Returns -1, 0 or 1 (useful for sorting)

Always prefer === and !==

== converts types before comparing, which leads to surprises:

PHP
<?php

var_dump(0 == '');        // false in PHP 8 (true in PHP 7!)
var_dump('1' == '01');    // true: both look like the number 1
var_dump(100 == '1e2');   // true: "1e2" is scientific notation for 100
var_dump(null == false);  // true

With === none of these surprises happen:

PHP
<?php

var_dump('1' === '01');   // false
var_dump(null === false); // false

Use === and !== by default. Reach for == only when you deliberately want type conversion, and leave a comment saying so.

Logical operators

Combine conditions:

OperatorMeaning
&&And: both must be true
||Or: at least one must be true
!Not: flips true and false
PHP
<?php

$age = 20;
$hasTicket = true;

$canEnter = $age >= 18 && $hasTicket;
$needsHelp = !$hasTicket || $age < 12;

PHP stops evaluating as soon as the answer is known. In $user !== null && $user->isActive(), the method is only called when $user exists. This "short-circuit" behaviour is useful for guarding against errors.

The null coalescing operator ??

?? returns the left value if it exists and is not null, otherwise the right value. It is the cleanest way to read optional input:

PHP
<?php

$page = $_GET['page'] ?? 1;
$theme = $settings['theme'] ?? 'light';

No warnings are raised if page is missing. There is an assignment version too: $name ??= 'Guest'; sets $name only if it is null or undefined.

The ternary operator

condition ? valueIfTrue : valueIfFalse picks one of two values:

PHP
<?php

$score = 72;
$result = $score >= 70 ? 'pass' : 'fail';

echo $result; // pass

Keep ternaries short. If you need to nest them, use an if statement or match expression instead (next lessons). PHP 8 does not allow unbracketed nested ternaries at all, because they were so often misread.

Summary

  • Arithmetic follows normal maths rules; intdiv() and % handle whole-number division.
  • Shortcuts like +=, .= and ++ update a variable in place.
  • Compare with === and !== unless you specifically want type conversion.
  • &&, || and ! combine conditions and short-circuit.
  • ?? supplies defaults; ? : chooses between two values.

Further reading