Skip to main content
    Courses/PHP/Operators & Expressions

    Lesson 3 • Beginner

    Operators & Expressions ➕

    By the end of this lesson you'll be able to do maths, join text, and compare values in PHP — and you'll know the one comparison rule (=== over ==) that prevents a whole category of bugs.

    What You'll Learn in This Lesson

    • Do arithmetic with + - * / % and ** (exponentiation)
    • Join text with the . operator and append with .=
    • Use assignment shortcuts (+= -= ++ --) to update variables
    • Tell == (loose) from === (strict) and know which to reach for
    • Compare with <=> (spaceship) and combine conditions with && || !
    • Provide fallbacks with ?? and ??=, and write one-line ternary choices

    1️⃣ Arithmetic Operators

    An operator is a symbol that acts on values — the values it works on are called its operands. The arithmetic ones do exactly what you'd expect from a calculator: +, -, *, and /. Two are worth a closer look: % (modulus) gives the remainder after dividing — great for "is this number even?" — and ** raises a number to a power. Note that / can return a float (a decimal) even when both inputs are whole numbers.

    The six arithmetic operators
    <?php
    // An OPERATOR is a symbol that does something to values (the "operands").
    // $a + $b  ->  +  is the operator, $a and $b are the operands.
    
    $a = 15;
    $b = 4;
    
    // The six arithmetic operators. Each line builds a string with the . operator
    // (more on . in a moment) and echoes the result.
    echo "15 + 4  = " . ($a + $b)  . "\n";   // 19    addition
    echo "15 - 4  = " . ($a - $b)  . "\n";   // 11    subtraction
    echo "15 * 4  = " . ($a * $b)  . "\n";   // 60    multiplication
    echo "15 / 4  = " . ($a / $b)  . "\n";   // 3.75  division ALWAYS returns a float here
    echo "15 % 4  = " . ($a % $b)  . "\n";   // 3     modulus = the REMAINDER after dividing
    echo "15 ** 4 = " . ($a ** $b) . "\n";   // 50625 exponentiation: 15 to the power of 4
    ?>
    Output
    15 + 4  = 19
    15 - 4  = 11
    15 * 4  = 60
    15 / 4  = 3.75
    15 % 4  = 3
    15 ** 4 = 50625
    This is real code — run it for free atonecompiler.com/phpor in your own editor.

    2️⃣ Joining Text: . and .=

    This is the one that trips up newcomers from other languages: PHP joins strings with the dot (.), not the plus sign. Writing "5" + "3" tries to add them as numbers (giving 8), whereas "5" . "3" glues them into "53". The .= operator is the text version of += — it appends to a string you already have.

    Concatenation with . and .=
    <?php
    // PHP joins strings with the DOT ( . ), NOT the + sign.
    // (Using + on two strings tries to ADD them as numbers — a classic trap.)
    
    $first = "Ada";
    $last  = "Lovelace";
    
    // '.' glues pieces together. Note the literal space " " in the middle.
    $fullName = $first . " " . $last;
    echo $fullName . "\n";          // Ada Lovelace
    
    // '.=' APPENDS to a string in place — like += but for text.
    $greeting = "Hello";
    $greeting .= ", " . $first;      // adds ", Ada" onto the end
    $greeting .= "!";                // adds "!" onto the end
    echo $greeting . "\n";          // Hello, Ada!
    
    // Inside "double quotes" PHP also expands variables directly — handy too.
    echo "Welcome back, $first.\n"; // Welcome back, Ada.
    ?>
    Output
    Ada Lovelace
    Hello, Ada!
    Welcome back, Ada.
    This is real code — run it for free atonecompiler.com/phpor in your own editor.

    3️⃣ Assignment & Increment

    A single = is assignment — it stores the value on the right into the variable on the left (it is not "equals"; that's ==, coming next). The compound operators (+= -= *= /= %=) do a calculation and reassign in one step, so $x += 5 just means $x = $x + 5. To bump a value by exactly 1, use ++ or -- — and watch the position: $n++ uses the value then adds, while ++$n adds then uses.

    Assignment shortcuts and ++ / --
    <?php
    // '=' is ASSIGNMENT: it puts the value on the right into the variable on the left.
    // The compound operators below do a calculation AND reassign in one step.
    
    $x = 10;            echo "start:  \$x = $x\n";   // start:  $x = 10
    
    $x += 5;            echo "+= 5:   \$x = $x\n";   // 15   same as $x = $x + 5
    $x -= 3;            echo "-= 3:   \$x = $x\n";   // 12   same as $x = $x - 3
    $x *= 2;            echo "*= 2:   \$x = $x\n";   // 24   same as $x = $x * 2
    $x /= 4;            echo "/= 4:   \$x = $x\n";   // 6    same as $x = $x / 4
    $x %= 4;            echo "%= 4:   \$x = $x\n";   // 2    same as $x = $x % 4
    
    // ++ and -- add or subtract exactly 1. POSITION matters:
    $n = 5;
    echo "\$n++ gives " . ($n++) . ", then \$n is $n\n"; // gives 5, then 6 (use-then-add)
    echo "++\$n gives " . (++$n) . ", then \$n is $n\n"; // gives 7, then 7 (add-then-use)
    ?>
    Output
    start:  $x = 10
    += 5:   $x = 15
    -= 3:   $x = 12
    *= 2:   $x = 24
    /= 4:   $x = 6
    %= 4:   $x = 2
    $n++ gives 5, then $n is 6
    ++$n gives 7, then $n is 7
    This is real code — run it for free atonecompiler.com/phpor in your own editor.

    4️⃣ Comparison: == vs === and the Spaceship

    Comparison operators ask a yes/no question and hand back a boolean (true or false). The most important rule in this whole lesson lives here. == is loose equality: it converts types first, so 5 == "5" is true. === is strict equality: the value and the type must match, so 5 === "5" is false. Prefer === almost always — loose comparison ("type juggling") is a famous source of bugs. The other operators are != (not equal), <, >, <=, >=, and the spaceship <=>, which returns -1, 0, or 1 for a three-way compare (ideal for sorting).

    Comparison and the spaceship operator
    <?php
    // COMPARISON operators ask a yes/no question and return a bool (true / false).
    // var_export() prints true/false literally so you can SEE the answer.
    
    // == is LOOSE equality: it converts types first, so surprises happen.
    // === is STRICT equality: values AND types must match. Prefer === almost always.
    echo "5 == '5'   -> "; var_export(5 == "5");   echo "\n"; // true  (string "5" becomes 5)
    echo "5 === '5'  -> "; var_export(5 === "5");  echo "\n"; // false (int vs string)
    echo "0 == 'a'   -> "; var_export(0 == "a");   echo "\n"; // false (modern PHP 8+)
    echo "1 != 2     -> "; var_export(1 != 2);     echo "\n"; // true  (not equal)
    echo "3 <= 3     -> "; var_export(3 <= 3);     echo "\n"; // true  (less than OR equal)
    
    // The SPACESHIP <=> returns -1, 0, or 1 for a three-way compare.
    // Perfect for sorting: it tells you "smaller", "equal", or "larger".
    echo "1 <=> 5 -> " . (1 <=> 5) . "\n";   // -1  left is smaller
    echo "5 <=> 5 -> " . (5 <=> 5) . "\n";   //  0  they are equal
    echo "9 <=> 5 -> " . (9 <=> 5) . "\n";   //  1  left is larger
    ?>
    Output
    5 == '5'   -> true
    5 === '5'  -> false
    0 == 'a'   -> false
    1 != 2     -> true
    3 <= 3     -> true
    1 <=> 5 -> -1
    5 <=> 5 -> 0
    9 <=> 5 -> 1
    This is real code — run it for free atonecompiler.com/phpor in your own editor.

    Now you try. The script below is almost complete — fill in each ___ using the 👉 hint, then run it and check it against the Output panel.

    🎯 Your turn: total with maths + concatenation
    <?php
    // 🎯 YOUR TURN — fill in each blank marked ___ , then run it.
    // Goal: build a full sentence using arithmetic AND string concatenation.
    
    $price = 8;
    $qty   = 3;
    
    // 1) Work out the total cost (price times quantity)
    $total = $price ___ $qty;          // 👉 replace ___ with the multiply operator ( * )
    
    // 2) Join the pieces into one string with the DOT operator
    echo "Total: " ___ $total ___ " dollars\n"; // 👉 replace each ___ with a dot ( . )
    
    // ✅ Expected output:
    //    Total: 24 dollars
    ?>
    Output
    Total: 24 dollars
    Replace the first ___ with * and the others with the dot . operator, then run it. You should get Total: 24 dollars.

    5️⃣ Logical Operators

    Logical operators combine true/false values so you can ask compound questions. && (AND) is true only when both sides are true; || (OR) is true when either side is true; ! (NOT) flips a boolean. PHP also has word forms and / or — they look friendlier but bind looser than =, which causes a classic surprise shown below. The advice is simple: use && and ||.

    &&, ||, ! (and the 'and' gotcha)
    <?php
    // LOGICAL operators combine true/false values into a single yes/no answer.
    //   &&  AND  -> true only if BOTH sides are true
    //   ||  OR   -> true if EITHER side is true
    //   !   NOT  -> flips true to false and back
    
    $loggedIn = true;
    $isAdmin  = false;
    
    var_export($loggedIn && $isAdmin); echo "  (&&  both? no)\n";  // false
    var_export($loggedIn || $isAdmin); echo "  (||  either? yes)\n"; // true
    var_export(!$isAdmin);             echo "  (!   flip false)\n";  // true
    
    // 'and' / 'or' are word versions that do the same logic BUT bind very loosely —
    // looser than '='. This line surprises people:
    $result = true and false;   // reads as ($result = true) and false  -> $result is TRUE
    var_export($result);        echo "  (gotcha: 'and' is looser than '=')\n";
    
    // Use && and || to stay safe. This behaves as expected:
    $result = true && false;    // $result is FALSE, as you'd hope
    var_export($result);        echo "  (&& binds tighter than '=')\n";
    ?>
    Output
    false  (&&  both? no)
    true  (||  either? yes)
    true  (!   flip false)
    true  (gotcha: 'and' is looser than '=')
    false  (&& binds tighter than '=')
    This is real code — run it for free atonecompiler.com/phpor in your own editor.

    6️⃣ Null Coalescing & Ternary

    These operators let you pick a value in one line. ?? (null coalescing) means "use the left value, but if it's null or unset, use the right" — perfect for defaults, and it won't warn on undefined variables. ??= assigns the fallback only when the variable is currently null. The ternary condition ? a : b is a compact if/else: it returns a when the condition is true, otherwise b. The short ternary ?: returns the left value if it's truthy. The key difference: ?? only reacts to null, while ?: reacts to any falsy value ("", 0, false).

    ?? , ??= , ternary and short ternary
    <?php
    // ?? NULL COALESCING: "use the left value, but if it's null/unset, use the right."
    $username = null;
    $name = $username ?? "Guest";     // $username is null, so fall back to "Guest"
    echo "name: $name\n";            // name: Guest
    
    // ??= assigns the fallback ONLY if the variable is currently null/unset.
    $config = null;
    $config ??= "default";            // was null -> becomes "default"
    echo "config: $config\n";        // config: default
    
    // TERNARY  condition ? valueIfTrue : valueIfFalse  — a one-line if/else.
    $age = 20;
    $status = ($age >= 18) ? "adult" : "minor";
    echo "status: $status\n";        // status: adult
    
    // SHORT TERNARY ?:  returns the left value if it's "truthy", else the right.
    // Careful: ?: checks truthiness ("" and 0 count as false); ?? only checks null.
    $nickname = "";
    echo "nick: " . ($nickname ?: "Anonymous") . "\n"; // "" is falsy -> Anonymous
    ?>
    Output
    name: Guest
    config: default
    status: adult
    nick: Anonymous
    This is real code — run it for free atonecompiler.com/phpor in your own editor.

    One more guided exercise. Pick the operator each comment asks for, then run it and compare with the Output panel.

    🎯 Your turn: strict compare + a fallback
    <?php
    // 🎯 YOUR TURN — choose the RIGHT comparison operator.
    // var_export prints true / false so you can check yourself.
    
    $input = "5";   // came from a form, so it's a STRING "5", not the number 5
    
    // 1) We want this to be FALSE because a string is not the same TYPE as a number.
    //    Use the STRICT equality operator.
    var_export($input ___ 5);  echo "\n";   // 👉 replace ___ with strict-equal ( === )
    
    // 2) We want a fallback when $nickname is null. Use null coalescing.
    $nickname = null;
    echo ($nickname ___ "Guest") . "\n";    // 👉 replace ___ with the ?? operator
    
    // ✅ Expected output:
    //    false
    //    Guest
    ?>
    Output
    false
    Guest
    Use === for the strict comparison and ?? for the fallback. The output should be false then Guest.

    7️⃣ Operator Precedence

    Precedence is the order operators run in — exactly like school maths, where * happens before +. So 2 + 3 * 4 is 14, not 20. Comparisons run before && and ||, which is usually what you want. When in any doubt, add parentheses ( ) — they force your order and make intent obvious to the next reader (often future you).

    Precedence and parentheses
    <?php
    // PRECEDENCE is the order operators run in, like maths: * before +.
    echo 2 + 3 * 4, "\n";        // 14, NOT 20 — * happens before +
    
    // Parentheses ( ) force your own order and make intent obvious.
    echo (2 + 3) * 4, "\n";      // 20 — the addition is forced first
    
    // Comparison runs before && / ||, so this reads naturally:
    $score = 85;
    $pass = $score >= 50 && $score <= 100;  // (score>=50) && (score<=100)
    var_export($pass); echo "\n";          // true
    
    // When unsure, ADD PARENTHESES. They cost nothing and remove all doubt.
    $ok = ($score >= 50) && ($score <= 100);
    var_export($ok); echo "\n";            // true
    ?>
    Output
    14
    20
    true
    true
    This is real code — run it for free atonecompiler.com/phpor in your own editor.

    Common Errors (and the fix)

    • A comparison with == behaves weirdly — you hit type juggling. With loose ==, PHP converts types first, so "5" == 5 is true and other surprises lurk. The fix is almost always to use strict ===, which also checks the type.
    • Your if is always true — you wrote if ($x = 5) with one =. A single = assigns 5 to $x (and the result is truthy), so the branch always runs. Comparison needs == or ===.
    • "5" + "3" gave 8, not "53" — in PHP + is maths only, so it converts numeric strings and adds them. To join text, use the dot: "5" . "3".
    • Comparing a number to a string of text behaves unexpectedly — mixing types in a comparison is risky. If a value came from a form it's a string; convert it first with (int)$value (or (float)) before comparing, then use ===.
    • $total = $a + $b * 2 isn't what you expected — that's precedence: * runs before +. Wrap the part you want first in parentheses: ($a + $b) * 2.

    Pro Tips

    • 💡 Default to ===. Reach for loose == only when you deliberately want type conversion — which is rare.
    • 💡 Use ?? for missing data, ?: for "empty-ish" data. ?? reacts only to null; ?: also catches "" and 0.
    • 💡 Stick to && / ||, not the word forms — their looser precedence causes the $x = true and false trap.
    • 💡 Parentheses are free. When precedence is unclear, add them; readable beats clever.

    📋 Quick Reference — PHP Operators

    OperatorMeaningExample → Result
    + - * / % **Arithmetic15 % 4 → 3
    . .=String join / append"Hi " . $name
    = += -= *= /=Assign / update$x += 5
    ++ --Increment / decrement$n++ → adds 1
    == ===Loose / strict equal5 === "5" → false
    != < > <= >=Not-equal / ordering3 <= 3 → true
    <=>Spaceship (3-way)1 <=> 5 → -1
    && || !Logical and / or / not$a && $b
    ?? ??=Null coalescing$x ?? "default"
    ? : ?:Ternary / short ternary$age >= 18 ? "a" : "b"

    Frequently Asked Questions

    Q: What is the difference between == and === in PHP?

    == is loose equality: it converts the two values to a common type before comparing, so 5 == "5" is true and (in older PHP) 0 == "" could be true. === is strict equality: the values must match AND be the same type, so 5 === "5" is false because one is an integer and the other a string. Prefer === almost everywhere — it avoids the surprising type-juggling bugs that loose comparison causes.

    Q: Why does PHP use a dot (.) to join strings instead of +?

    PHP reserves + for arithmetic only, so it picked the dot (.) as the string concatenation operator. This means "5" + "3" gives the number 8 (PHP converts the strings and adds them), while "5" . "3" gives the string "53". If you come from JavaScript or Python where + joins text, this is the single most common mistake — use . for text and += has a text twin called .= .

    Q: When should I use ?? versus the short ternary ?: ?

    Use ?? (null coalescing) when you only care whether a value is null or unset — $name = $input ?? "Guest" gives "Guest" only when $input is null, and it does not raise a warning for undefined variables. Use ?: (short ternary) when you want the fallback for ANY falsy value, including 0, "", "0", and false. In short: ?? checks for null; ?: checks for truthiness.

    Q: What does the spaceship operator <=> do?

    The spaceship operator <=> compares two values and returns -1 if the left is smaller, 0 if they are equal, and 1 if the left is larger. It was added in PHP 7 and is mainly used inside sort callbacks: in usort($arr, fn($x, $y) => $x <=> $y) it tells PHP the correct order in a single expression, replacing the older if/elseif comparison code.

    Q: Why does my condition behave strangely with 'and' instead of '&&'?

    PHP has two AND operators (&& and the word 'and') and two OR operators (|| and 'or'), and they have different precedence. The word versions bind LOOSER than the assignment operator =, so $x = true and false actually runs as ($x = true) and false, leaving $x as true. To avoid this trap, stick to && and || in conditions — they bind tighter than = and behave the way you expect.

    Mini-Challenge: Shopping Receipt

    No code is filled in this time — just a brief and an outline. Write it yourself, run it on onecompiler.com/php or your own machine, then check your result against the expected output in the comments. This is exactly the write-run-check loop you'll use on every real script.

    🎯 Mini-Challenge: build a receipt with maths, . and a ternary
    <?php
    // 🎯 MINI-CHALLENGE: A tiny shopping receipt.
    // No code is filled in — work from the steps below, then run it.
    //
    // 1. Make $unitPrice = 12 and $quantity = 4
    // 2. Calculate $subtotal  (unit price * quantity)
    // 3. Calculate $tax = $subtotal * 0.1   (10% tax)
    // 4. Calculate $total = $subtotal + $tax
    // 5. echo three lines using the . operator, e.g.:
    //       "Subtotal: " . $subtotal
    //    Use \n at the end of each so they sit on separate lines.
    // 6. Add a discount label with SHORT TERNARY:
    //       $label = $total > 50 ? "BIG ORDER" : "small order";
    //
    // ✅ Expected output:
    //    Subtotal: 48
    //    Tax: 4.8
    //    Total: 52.8
    //    Label: BIG ORDER
    
    // your code here
    ?>
    Calculate a subtotal, tax (10%), and total, print three labelled lines with the . operator, then pick a label with a ternary. Match the expected output in the comments.

    🎉 Lesson Complete!

    • ✅ Arithmetic uses + - * / % **; % is the remainder and / can return a float
    • ✅ Join text with the dot . (and append with .=) — never +
    • += -= ++ -- update a variable in place; ++$n vs $n++ differ by position
    • Prefer === over == — strict equality checks the type too and avoids type-juggling bugs
    • <=> compares three ways; && || ! combine conditions
    • ?? / ??= give defaults; the ternary ?: is a one-line if/else; parentheses settle precedence
    • Next lesson: Control Flow — use these comparisons inside if/else and switch to make decisions

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service