Lesson 2.2: Operators and Expressions
Operators are like the action words in your code—they tell PHP what to do with your information. Think of them as the verbs in a sentence. While variables hold your data (like nouns), operators transform, compare, and combine that data to create useful results. They're the tools that turn static information into dynamic, interactive programs.
Imagine you're working at a cash register. You have numbers (the prices), but you need actions to work with them—adding items together, calculating tax, checking if someone has enough money to pay. Operators provide exactly these actions for your code. They let you perform math, make comparisons, and combine information in countless ways.
Arithmetic Operators: Basic Math Operations
Arithmetic operators handle the fundamental mathematical operations you use every day. These are your essential tools for any program that works with numbers—from simple calculations to complex financial applications.
<?php
$firstNumber = 15;
$secondNumber = 4;
// Basic arithmetic operations
$addition = $firstNumber + $secondNumber; // 19
$subtraction = $firstNumber - $secondNumber; // 11
$multiplication = $firstNumber * $secondNumber; // 60
$division = $firstNumber / $secondNumber; // 3.75
$remainder = $firstNumber % $secondNumber; // 3 (what's left over)
$power = $firstNumber ** 2; // 225 (15 squared)
echo "Adding: $firstNumber + $secondNumber = $addition\n";
echo "Subtracting: $firstNumber - $secondNumber = $subtraction\n";
echo "Multiplying: $firstNumber * $secondNumber = $multiplication\n";
echo "Dividing: $firstNumber / $secondNumber = $division\n";
echo "Remainder: $firstNumber % $secondNumber = $remainder\n";
echo "Power: $firstNumber ** 2 = $power\n";
?>
The modulus operator (%
) deserves special attention because it's incredibly useful but not immediately obvious. It gives you the remainder after division. For example, 15 divided by 4 equals 3 with 3 left over. The modulus operator returns that leftover amount. You'll use this for determining if numbers are even or odd, cycling through lists, or creating repeating patterns.
<?php
$number = 17;
// Check if a number is even or odd
if ($number % 2 === 0) {
echo "$number is even\n";
} else {
echo "$number is odd\n";
}
// Create a repeating pattern
for ($i = 1; $i <= 10; $i++) {
$position = $i % 3;
if ($position === 1) {
echo "Red ";
} elseif ($position === 2) {
echo "Green ";
} else {
echo "Blue ";
}
}
echo "\n";
?>
Assignment Operators: Storing and Updating Values
Assignment operators don't just store values—they combine storage with mathematical operations, making your code more concise and often more readable. The basic assignment operator (=
) puts a value into a variable, but the compound assignment operators do math and store the result in one step.
<?php
$bankAccount = 100;
echo "Starting balance: $bankAccount\n";
// Basic assignment
$bankAccount = 150;
echo "After deposit: $bankAccount\n";
// Compound assignment operators - math + storage combined
$bankAccount += 25; // Same as: $bankAccount = $bankAccount + 25
echo "After earning: $bankAccount\n";
$bankAccount -= 10; // Same as: $bankAccount = $bankAccount - 10
echo "After spending: $bankAccount\n";
$bankAccount *= 1.05; // Same as: $bankAccount = $bankAccount * 1.05 (5% interest)
echo "After interest: $bankAccount\n";
$bankAccount /= 2; // Same as: $bankAccount = $bankAccount / 2
echo "After splitting: $bankAccount\n";
// Working with strings too
$message = "Hello";
$message .= " World"; // Same as: $message = $message . " World"
echo "Combined message: $message\n";
?>
These compound operators save typing and make your intentions clearer. When you see $score += 10
, you immediately understand you're adding 10 to the existing score, rather than replacing it entirely.
Increment and Decrement: Small Changes with Big Impact
These operators increase or decrease values by exactly one, but their placement affects when the change happens. This timing difference becomes crucial in loops and complex calculations.
<?php
$counter = 5;
// Pre-increment: change first, then use the new value
echo "Pre-increment: " . ++$counter . "\n"; // Shows 6, counter is now 6
echo "Current value: $counter\n"; // Shows 6
// Post-increment: use the current value, then change it
echo "Post-increment: " . $counter++ . "\n"; // Shows 6, but counter becomes 7
echo "Current value: $counter\n"; // Shows 7
// Same behavior applies to decrement
$attempts = 3;
echo "Attempts remaining: " . --$attempts . "\n"; // Shows 2, attempts is now 2
echo "Using attempt: " . $attempts-- . "\n"; // Shows 2, attempts becomes 1
echo "Attempts left: $attempts\n"; // Shows 1
// Practical example: processing a list
$items = ["apple", "banana", "cherry"];
$index = 0;
while ($index < count($items)) {
echo "Processing item " . ($index + 1) . ": " . $items[$index] . "\n";
$index++; // Move to next item after processing current one
}
?>
The difference between ++$variable
and $variable++
seems small, but it can drastically change how your programs behave. Pre-increment changes the value immediately, while post-increment uses the old value first, then changes it.
Comparison Operators: Making Decisions
Comparison operators examine relationships between values and return true or false answers. They're the foundation of every decision your program makes—from simple "is the user old enough?" checks to complex business logic.
<?php
$userAge = 25;
$minimumAge = 18;
$price = 99.99;
$budget = 100;
// Basic comparisons
$isAdult = $userAge >= $minimumAge; // true
$canAfford = $price <= $budget; // true
$exactMatch = $price == 99.99; // true
$strictMatch = $price === "99.99"; // false (different types)
$notEqual = $userAge != 30; // true
$strictlyNotEqual = $userAge !== "25"; // true (different types)
echo "Is adult: " . ($isAdult ? "Yes" : "No") . "\n";
echo "Can afford: " . ($canAfford ? "Yes" : "No") . "\n";
echo "Exact price match: " . ($exactMatch ? "Yes" : "No") . "\n";
echo "Strict type match: " . ($strictMatch ? "Yes" : "No") . "\n";
// Dangerous vs safe comparisons
$userInput = "42";
$storedNumber = 42;
if ($userInput == $storedNumber) {
echo "Loose comparison: These are considered equal\n";
}
if ($userInput === $storedNumber) {
echo "This won't print - strict comparison failed\n";
} else {
echo "Strict comparison: Different types (text vs number)\n";
}
// Range checking
$temperature = 75;
if ($temperature >= 70 && $temperature <= 80) {
echo "Perfect temperature!\n";
} else {
echo "Too hot or too cold\n";
}
?>
The difference between loose (==
) and strict (===
) comparison is crucial. Loose comparison converts types before comparing (so "42" equals 42), while strict comparison checks both the value and the type (so "42" does not equal 42). For most situations, especially when dealing with user input, strict comparison prevents subtle bugs.
Logical Operators: Combining Conditions
Logical operators let you combine multiple true/false conditions into more complex decisions. They work like the words "and," "or," and "not" in everyday speech, helping you create sophisticated decision-making logic.
<?php
$hasAccount = true;
$isLoggedIn = true;
$hasPermission = false;
$isAdmin = false;
// AND operator - all conditions must be true
if ($hasAccount && $isLoggedIn) {
echo "Welcome back!\n";
}
// OR operator - at least one condition must be true
if ($hasPermission || $isAdmin) {
echo "Access granted to admin panel\n";
} else {
echo "Access denied - insufficient privileges\n";
}
// NOT operator - flips true to false, false to true
if (!$hasPermission) {
echo "Limited access mode\n";
}
// Complex combinations
$userAge = 20;
$hasLicense = true;
$hasInsurance = true;
if ($userAge >= 18 && $hasLicense && $hasInsurance) {
echo "You can rent a car\n";
} else {
echo "Car rental not available\n";
}
// Order matters with logical operators
$username = "admin";
$password = "secret123";
if ($username === "admin" && $password === "secret123") {
echo "Admin login successful\n";
}
// Short-circuit evaluation - PHP stops checking once it knows the answer
$expensiveCheck = false;
if (false && $expensiveCheck) {
// $expensiveCheck never gets evaluated because false && anything is always false
echo "This won't run\n";
}
?>
Logical operators use "short-circuit evaluation," which means PHP stops checking conditions once it knows the final answer. With AND (&&
), if the first condition is false, PHP doesn't bother checking the rest because the whole thing will be false anyway. With OR (||
), if the first condition is true, PHP skips the rest because one true condition makes the whole thing true.
String Operators: Working with Text
PHP provides specific operators for combining and manipulating text. These become essential when you're building user interfaces, generating messages, or working with any kind of textual data.
<?php
$firstName = "Sarah";
$lastName = "Johnson";
$age = 28;
// Concatenation operator - joins strings together
$fullName = $firstName . " " . $lastName;
echo "Full name: $fullName\n";
// Concatenation assignment - adds to existing string
$greeting = "Hello, ";
$greeting .= $firstName;
$greeting .= "! Welcome to our site.";
echo "$greeting\n";
// Building complex messages
$itemName = "Wireless Headphones";
$price = 79.99;
$tax = $price * 0.08;
$total = $price + $tax;
$receipt = "Item: " . $itemName . "\n";
$receipt .= "Price: $" . number_format($price, 2) . "\n";
$receipt .= "Tax: $" . number_format($tax, 2) . "\n";
$receipt .= "Total: $" . number_format($total, 2) . "\n";
echo $receipt;
// Working with user input
$userCity = "New York";
$userState = "NY";
$userZip = "10001";
$fullAddress = $userCity . ", " . $userState . " " . $userZip;
echo "Shipping to: $fullAddress\n";
// Creating lists
$hobbies = ["reading", "gaming", "cooking"];
$hobbyList = "My hobbies: " . implode(", ", $hobbies);
echo "$hobbyList\n";
?>
String concatenation with the dot (.
) operator is fundamental in PHP. Unlike some languages that use +
for both numbers and strings, PHP keeps them separate—+
is only for math, .
is only for combining text.
Operator Precedence: Order of Operations
Just like in math class, PHP follows specific rules about which operations happen first. Understanding precedence prevents calculation errors and unexpected results. When in doubt, use parentheses to make your intentions crystal clear.
<?php
// Without parentheses - follows mathematical precedence
$result1 = 2 + 3 * 4; // 14 (not 20) - multiplication first
$result2 = 10 / 2 + 3; // 8 (not 2) - division first
$result3 = 5 + 10 % 3; // 6 (not 0) - modulus first
echo "Mathematical precedence:\n";
echo "2 + 3 * 4 = $result1\n";
echo "10 / 2 + 3 = $result2\n";
echo "5 + 10 % 3 = $result3\n";
// With parentheses - forces specific order
$result4 = (2 + 3) * 4; // 20
$result5 = 10 / (2 + 3); // 2
$result6 = (5 + 10) % 3; // 0
echo "\nForced precedence with parentheses:\n";
echo "(2 + 3) * 4 = $result4\n";
echo "10 / (2 + 3) = $result5\n";
echo "(5 + 10) % 3 = $result6\n";
// Real-world example: calculating total price
$itemPrice = 29.99;
$quantity = 3;
$taxRate = 0.08;
$shippingCost = 5.99;
// Wrong way - unclear order of operations
$wrongTotal = $itemPrice * $quantity + $taxRate + $shippingCost;
// Right way - clear, explicit calculation
$subtotal = $itemPrice * $quantity;
$tax = $subtotal * $taxRate;
$correctTotal = $subtotal + $tax + $shippingCost;
echo "\nPrice calculation:\n";
echo "Wrong calculation: $wrongTotal\n";
echo "Correct calculation: $correctTotal\n";
// Complex expression broken down for clarity
$a = 5;
$b = 10;
$c = 2;
// Complex formula: (a + b) * c / (a - 1) + b % c
$step1 = $a + $b; // 15
$step2 = $a - 1; // 4
$step3 = $step1 * $c; // 30
$step4 = $step3 / $step2; // 7.5
$step5 = $b % $c; // 0
$finalResult = $step4 + $step5; // 7.5
echo "\nStep-by-step calculation:\n";
echo "($a + $b) = $step1\n";
echo "($a - 1) = $step2\n";
echo "$step1 * $c = $step3\n";
echo "$step3 / $step2 = $step4\n";
echo "$b % $c = $step5\n";
echo "Final result: $finalResult\n";
?>
When you're writing complex calculations, break them into smaller steps with descriptive variable names. This approach makes your code easier to understand, debug, and modify later. Other developers (including future you) will thank you for the clarity.
Practical Applications: Real-World Examples
Let's combine different operators to solve common programming problems. These examples show how operators work together in practical situations you'll encounter when building web applications.
<?php
// Shopping cart calculation
$items = [
["name" => "T-Shirt", "price" => 19.99, "quantity" => 2],
["name" => "Jeans", "price" => 49.99, "quantity" => 1],
["name" => "Sneakers", "price" => 79.99, "quantity" => 1]
];
$subtotal = 0;
echo "Shopping Cart:\n";
echo "==============\n";
foreach ($items as $item) {
$itemTotal = $item["price"] * $item["quantity"];
$subtotal += $itemTotal;
echo $item["name"] . " x" . $item["quantity"] . " = $" . number_format($itemTotal, 2) . "\n";
}
$taxRate = 0.08;
$tax = $subtotal * $taxRate;
$shippingThreshold = 50.00;
$shippingCost = ($subtotal >= $shippingThreshold) ? 0 : 5.99;
$total = $subtotal + $tax + $shippingCost;
echo "\nSubtotal: $" . number_format($subtotal, 2) . "\n";
echo "Tax (8%): $" . number_format($tax, 2) . "\n";
echo "Shipping: $" . number_format($shippingCost, 2) . "\n";
echo "Total: $" . number_format($total, 2) . "\n";
// User authentication system
$username = "sarah_j";
$password = "mySecurePassword123";
$accountLocked = false;
$loginAttempts = 2;
$maxAttempts = 3;
echo "\nLogin System:\n";
echo "=============\n";
if ($accountLocked) {
echo "Account is locked. Contact support.\n";
} elseif ($loginAttempts >= $maxAttempts) {
echo "Too many failed attempts. Account locked.\n";
$accountLocked = true;
} elseif ($username === "sarah_j" && $password === "mySecurePassword123") {
echo "Login successful! Welcome, Sarah.\n";
$loginAttempts = 0; // Reset attempts on successful login
} else {
$loginAttempts++;
$remainingAttempts = $maxAttempts - $loginAttempts;
echo "Invalid credentials. $remainingAttempts attempts remaining.\n";
}
// Grade calculation system
$homework = 85;
$midterm = 78;
$final = 92;
$participation = 95;
// Weighted average calculation
$homeworkWeight = 0.30;
$midtermWeight = 0.25;
$finalWeight = 0.35;
$participationWeight = 0.10;
$finalGrade = ($homework * $homeworkWeight) +
($midterm * $midtermWeight) +
($final * $finalWeight) +
($participation * $participationWeight);
echo "\nGrade Calculation:\n";
echo "==================\n";
echo "Homework (30%): $homework\n";
echo "Midterm (25%): $midterm\n";
echo "Final (35%): $final\n";
echo "Participation (10%): $participation\n";
echo "Final Grade: " . number_format($finalGrade, 1) . "%\n";
// Determine letter grade
if ($finalGrade >= 90) {
$letterGrade = "A";
} elseif ($finalGrade >= 80) {
$letterGrade = "B";
} elseif ($finalGrade >= 70) {
$letterGrade = "C";
} elseif ($finalGrade >= 60) {
$letterGrade = "D";
} else {
$letterGrade = "F";
}
echo "Letter Grade: $letterGrade\n";
?>
Common Mistakes and How to Avoid Them
Understanding common operator mistakes helps you write more reliable code and debug problems faster when they occur.
<?php
// Mistake 1: Confusing assignment (=) with comparison (==)
$userAge = 18;
// Wrong - this assigns 21 to $userAge, doesn't compare
if ($userAge = 21) {
echo "This will always run because assignment returns the assigned value\n";
}
// Right - this compares $userAge to 21
if ($userAge == 21) {
echo "This checks if user is 21\n";
}
// Mistake 2: Not understanding operator precedence
$price = 10;
$quantity = 5;
$taxRate = 0.08;
// Wrong - unclear what happens first
$badTotal = $price * $quantity + $taxRate;
// Right - explicit order with parentheses
$goodTotal = ($price * $quantity) * (1 + $taxRate);
echo "Bad calculation: $badTotal\n";
echo "Good calculation: $goodTotal\n";
// Mistake 3: Using wrong comparison operator
$userInput = "0";
// Loose comparison - "0" is considered equal to 0
if ($userInput == 0) {
echo "This runs because '0' == 0 is true\n";
}
// Strict comparison - "0" is not identical to 0
if ($userInput === 0) {
echo "This doesn't run because '0' !== 0\n";
} else {
echo "Strict comparison: '0' is not identical to 0\n";
}
// Mistake 4: Forgetting about integer division
$totalItems = 7;
$itemsPerPage = 3;
// This gives 2, not 2.33...
$pages = $totalItems / $itemsPerPage;
echo "Division result: $pages\n";
// Use ceil() to round up for pagination
$actualPages = ceil($totalItems / $itemsPerPage);
echo "Actual pages needed: $actualPages\n";
?>
Key Takeaways
Operators are the action elements that bring your variables to life. They enable calculations, comparisons, logical decisions, and text manipulation. Arithmetic operators handle math, assignment operators store and update values, comparison operators make decisions, logical operators combine conditions, and string operators work with text.
Understanding operator precedence ensures your calculations behave predictably. When building complex expressions, use parentheses liberally and break complicated calculations into smaller, named steps. This approach makes your code more readable and helps prevent subtle bugs.
The distinction between loose and strict comparison operators is particularly important when working with user input, where data types might not match your expectations. Always consider whether you need type conversion or strict type checking for your specific situation.
Practice combining different operators to solve real-world problems. The more you work with them, the more naturally you'll recognize which operators to use in different situations. Remember that clear, readable code with explicit parentheses and descriptive variable names is always better than clever shortcuts that obscure your intentions.