Skip to content
Theory · Operators and comparison · lesson 6 of 8

Logical operators

One comparison answers one question. But often the answer depends on two at once: whether the customer has a card and whether they bought more than a thousand's worth.

Let's go back to the shop. The cashier gives a discount by the rule "has a card AND the receipt is over 1000". By another rule a gift is due if "has a card OR today is a holiday". In PHP the words "and", "or" and "not" are written with logical operators.

PHP
<?php

$hasCard = true;
$sum = 800;
var_dump($hasCard && $sum > 1000); // bool(false)
var_dump($hasCard || $sum > 1000); // bool(true)
var_dump(!$hasCard); // bool(false)

Let's go through it line by line:

  1. In $hasCard && $sum > 1000 the comparison 800 > 1000 gives false, and the whole expression is false: && needs both sides to be true.
  2. In $hasCard || $sum > 1000 one true side is enough, and the card is there, so the result is true.
  3. !$hasCard flips the value: true becomes false.

Comparisons run before && and ||, so $sum > 1000 needs no parentheses.

Three operators

&&: "and"

$a && $b is true only when both sides are true. If at least one side is false, the whole expression is false.

||: "or"

$a || $b is true when at least one side is true. It is false only when both sides are false.

!: "not"

!$a gives true for a false value and false for a true one. If the value is not a bool, PHP first converts it the way (bool) does: !0 gives true. ! runs before a comparison: !$sum > 1000 means (!$sum) > 1000, so write !($sum > 1000).

The result of a logical operator is always a bool: 1 && 'a' gives bool(true). There is also xor, "exclusive or": it is true when exactly one side is true.

Short-circuit evaluation

The cashier will not total up the receipt if there is no card: the rule "card and a receipt over 1000" can no longer hold. PHP does the same, and this is called short-circuit evaluation:

  • if the left side of && is false, PHP does not evaluate the right side;
  • if the left side of || is true, it does not evaluate the right side either.

To see it, take a function that prints a word every time it is called:

PHP
function check()
{
    echo 'called ';
    return true;
}

var_dump(false && check()); // bool(false)
var_dump(true && check()); // called bool(true)

Let's go through it step by step:

  1. In false && check() the left side is false, the function is not called, and called is not printed.
  2. In true && check() the answer depends on the right side, so PHP calls check(). It prints called, and then var_dump prints bool(true).

The cashier picture is imprecise here. A real cashier may still glance at the receipt, but PHP does not touch the right side at all. The function in it is not called, and its echo never runs.

and and or are weaker than =

PHP also has the word operators and and or. They compute the same thing as && and ||, but they run at a different moment. The order of operations covers assignment too: && and || run before =, while and and or run after it.

PHP
$x = true && false;
var_dump($x); // bool(false)
$y = true and false;
var_dump($y); // bool(true)

Let's go through it line by line:

  1. On the first line && runs before =, and $x receives the result of true && false, which is false.
  2. On the second line = runs first: $y receives true. Then PHP computes and with false, and that result is not stored anywhere.

Interviewers often ask about the difference between && and and. The answer:

  • they compute the same value;
  • && binds tighter than =, while and binds weaker;
  • so in an assignment and gives a result nobody expects.

The same goes for || and or. In conditions and assignments, write &&, || and !.

Common mistake

The right to enter is stored in a variable with and:

PHP
$age = 20;
$hasTicket = false;
$canEnter = $age >= 18 and $hasTicket; // ✗
var_dump($canEnter); // bool(true)

There is no ticket, yet $canEnter holds true. The assignment ran first and stored the result of $age >= 18, and the ticket check went nowhere. PHP reports no error. With && the whole expression is evaluated before the store: $age >= 18 && $hasTicket gives false.

Key points

  • && is true when both sides are true, || when at least one is, and ! flips the value.
  • If the left side already decides the answer, PHP does not evaluate the right side.
  • and and or compute the same as && and ||, but they run after =.
  • Write && and || in assignments: $x = true and false leaves true in $x.