PHP Operators — Why Loose Equality Exposes User Accounts
A stored hash starting with '0e' plus digits made any password valid in PHP—a classic loose equality bug that strict === avoids.
- PHP operators are symbols that perform operations on values: arithmetic, comparison, logical, assignment, and more.
- Every comparison has two versions: loose (==) and strict (===). Mixing them causes most security bugs.
- Assignment operators (+=, -=, .=) combine operation and assignment in one step — use them to signal mutation.
- The null coalescing operator (??) and null-safe operator (?->) eliminate null errors in modern PHP.
- Performance insight: Loose comparisons are slower than strict because PHP must coerce types first.
- Production insight: Using == for password checks can bypass authentication when hash starts with '0e' (PHP type juggling).
Think of PHP operators as the verbs of your code — they're the action words that tell PHP what to DO with your data. Just like a calculator has buttons for +, -, × and ÷, PHP has symbols that add numbers, compare values, combine conditions, and assign data to variables. Without operators, you'd have data sitting around doing absolutely nothing — operators are what make things happen.
Every useful program ever written does at least one of three things: it calculates something, it compares something, or it makes a decision. None of those three things are possible without operators. Whether you're building a shopping cart that totals an order, a login form that checks if a password matches, or a news feed that filters posts by date — operators are working silently behind every single line of that logic. They are the engine of your code.
Before operators existed in programming languages, developers had to write verbose machine-level instructions just to add two numbers. Operators solve this by giving us a clean, readable shorthand. Instead of writing a function call like add($price, $tax), you just write $price + $tax. Instead of a function like isGreaterThan($age, 18), you write $age > 18. Operators compress complex intentions into a single character or short symbol — and PHP has a rich set of them covering arithmetic, comparison, logic, assignment, string manipulation and more.
By the end of this article you'll understand every major category of PHP operator, know exactly when to reach for each one, be able to read and write real PHP logic without second-guessing yourself, and you'll know the two or three sneaky mistakes that trip up even experienced developers. Let's build this up from the ground floor.
Arithmetic Operators — PHP as Your Calculator
Arithmetic operators are the ones you already know from primary school maths — they perform mathematical calculations on numbers. PHP gives you addition (+), subtraction (-), multiplication (), division (/), modulus (%), and exponentiation (*).
The one you might not recognise is modulus (%). It gives you the remainder after a division. So 10 % 3 is 1, because 3 goes into 10 three times (that's 9), leaving 1 left over. This is incredibly useful for things like checking whether a number is even or odd — an even number always has a remainder of 0 when divided by 2.
Exponentiation () is also worth highlighting. 2 8 means '2 to the power of 8', which is 256. You'll see this in security calculations, image sizing logic, and anywhere exponential growth matters.
PHP follows standard mathematical order of operations — multiplication and division before addition and subtraction. Use parentheses to override that order and make your intention crystal clear to anyone reading your code later.
10 / 3 returns 3.3333... (a float), not 3. If you need a whole number result from division, use intdiv(10, 3) which returns 3, or cast with (int)(10 / 3). Never assume PHP integer division truncates like it does in some other languages.bcdiv() for precise decimal arithmetic in payment systems.Assignment Operators — Storing and Updating Values in One Move
The basic assignment operator is =. But here's something beginners always get confused about: in PHP (and most programming languages), = does NOT mean 'equals'. It means 'take the value on the right and store it in the variable on the left'. Think of it like putting a label on a jar.
$score = 100 means: create a jar called score, and put the number 100 inside it.
PHP also gives you compound assignment operators that combine a maths operation with an assignment in one step. Instead of writing $score = $score + 10, you can write $score += 10. These aren't just shortcuts — they make your code easier to read because they communicate 'I am changing this existing value' rather than 'I am creating a new value'.
These compound operators exist for all arithmetic operations: +=, -=, =, /=, %=, *=. There's also .= for strings, which appends text to an existing string variable — something you'll use constantly when building HTML output or log messages.
Using these operators correctly is a sign of confident, fluent PHP code.
.= and echo once at the end: $html = ''; foreach($items as $item) { $html .= "<li>$item</li>"; } echo $html;. This is cleaner, testable, and easier to extend..= and using = instead inside a loop overwrites the variable each iteration..=..= is essential for string building — use it everywhere.Comparison and Logical Operators — The Decision-Making Duo
Comparison operators let PHP evaluate whether something is true or false by comparing two values. Every if statement, every loop condition, every filter you write depends on them. They always return a boolean — either true or false.
The most important distinction in PHP comparisons is == versus ===. Double-equals (==) checks if two values are loosely equal — PHP will try to convert types before comparing. Triple-equals (===) checks if two values are strictly equal — same value AND same type. This difference causes some of the nastiest bugs in PHP.
Logical operators combine multiple comparisons into one decision. && (AND) means both conditions must be true. || (OR) means at least one must be true. ! (NOT) flips a boolean — true becomes false and vice versa.
Think of && and || like real-world logic: 'You can enter the club if you have ID AND you're over 18' is &&. 'You get a discount if you're a student OR a senior' is ||.
There's also the spaceship operator <=>, which returns -1, 0, or 1 — perfect for sorting. And the null coalescing operator ??, which is one of PHP's most practical modern features.
0 == 'hello' evaluates to TRUE in PHP versions before 8.0, because PHP converted the string 'hello' to the integer 0. This caused serious security bugs in login systems where an empty password hash compared loosely to 0. Always use === for comparisons unless you have a specific reason not to. Make strict comparison your default habit from day one.==) can cause authentication bypass when string hashes start with '0e'.0 == 0 is true.===) for passwords, hashes, and IDs.===) checks value and type.==) coerces types — dangerous.?? for default values and <=> for custom sorting.String Operators and Concatenation
The dot operator (.) is PHP's string concatenation operator. It joins two strings into one. 'Hello' . ' World' produces 'Hello World'. You'll use it constantly when building messages, HTML, or any textual output.
There's also the compound assignment version (.=) which appends a string to the end of an existing variable. $str .= ' more text' is equivalent to $str = $str . ' more text'. This is your go-to tool for building strings in loops, constructing SQL queries, or accumulating log messages.
One subtle behavior: PHP automatically converts numbers to strings when using the dot operator. So 42 . ' apples' becomes '42 apples'. But be aware that concatenation has lower precedence than arithmetic, so 'Result: ' . 5 + 3 gives 'Result: 8'? Actually it gives '8' because the addition happens first — always wrap arithmetic in parentheses when concatenating.
.) has LOWER precedence than addition (+). So "Total: " . $price + $tax is evaluated as ("Total: " . $price) + $tax, which produces an unexpected result (and a warning in PHP 8). Always wrap arithmetic in parentheses when concatenating: "Total: " . ($price + $tax)..= inside a loop is efficient, but forgetting to initialise the variable with an empty string causes undefined variable warnings..= with a non-string..=.Increment, Decrement, Ternary, and Null-Safe Operators
PHP has a few more operator types that you'll use every day, and skipping them would leave real gaps in your understanding.
Increment and decrement operators (++ and --) increase or decrease a number by exactly 1. They come in two flavours: pre (++$count) changes the value first, then returns it. Post ($count++) returns the current value first, then changes it. This subtlety matters inside expressions.
The ternary operator (?:) is a compact if/else on one line. $result = condition ? 'if true' : 'if false'. Use it for simple assignments — not for complex logic where a full if/else is clearer.
The null-safe operator (?->, PHP 8.0+) lets you safely call methods on an object that might be null, without throwing an error. Before it existed, you'd need an if ($obj !== null) check every single time. Now one ?-> handles it gracefully.
?? instead of a ternary. $name = $input ?? 'default' is cleaner and more intentional than $name = ($input !== null) ? $input : 'default'. PHP 7.4+ even gives you ??= — the null coalescing assignment: $name ??= 'default' only assigns if $name is currently null.if ($i++ < $limit) uses the old value, so it may run one extra iteration.++$i) in loop conditions, or increment after the condition.?->) prevents errors from null objects.Bitwise and Type Operators — Low-Level Power and Type Safety
PHP also provides bitwise operators (&, |, ^, ~, <<, >>) that work on the binary representation of integers. These are often used for flags, permissions, or low‑level data manipulation. For example, you can pack multiple boolean flags into a single integer using bitwise OR and check them with AND.
Type operators help you inspect and enforce variable types. instanceof checks whether an object is an instance of a specific class (or implements an interface). The @ error control operator suppresses errors from an expression — but use it sparingly, as it often hides real problems.
Bitwise operators have lower precedence than comparison operators, so always parenthesize your expressions when mixing them.
@ error suppression hides critical failures like database connection errors.instanceof ensures type safety for operations.@ — it hides bugs that will bite you later.Loose Equality Bug Exposed User Accounts
password_verify() which uses strict comparison internally.- Never use loose comparison (==) for security-sensitive checks.
- Always use strict comparison (===) by default.
- Use PHP's built-in password functions which handle comparison safely.
if ($var = 'admin') vs if ($var === 'admin').var_dump() on the operands to see actual types..= (append) not = (assignment) inside the loop. var_dump the string each iteration.is_int(), is_string().Key takeaways
bccomp() or a tolerance for financial calculations.Common mistakes to avoid
5 patternsUsing == instead of === for equality checks
0 == 'admin' returns true in PHP 7 (because 'admin' converts to 0), which can allow empty-password logins to bypass authentication checks.Confusing = (assignment) with == (comparison) inside an if statement
if ($userRole = 'admin') instead of if ($userRole == 'admin'). The first one ASSIGNS 'admin' to $userRole and always evaluates to true — your if block runs for every user regardless of their actual role.if ('admin' === $userRole) so a typo like if ('admin' = $userRole) causes an obvious parse error.Misunderstanding post-increment vs pre-increment in expressions
$count = 5; $result = $count++ 2; — beginners expect $result to be 12 (6 × 2), but it's actually 10 (5 × 2), because $count is used before* being incremented.++$count) or put the increment on its own line before the expression to make the order unambiguous.Using AND/OR instead of &&/|| due to precedence differences
$result = true AND false; assigns true to $result and then evaluates false separately, because AND has lower precedence than =. This leads to logic bugs that are hard to spot.&& and || for logical operations. Reserve the words and, or, xor only when you need the extremely low precedence (rarely). When in doubt, use parentheses.Assuming floating point comparisons with == are safe
0.1 + 0.2 == 0.3 evaluates to false due to IEEE 754 rounding errors. This breaks financial calculations, payment validation, and score comparisons.bccomp() for decimal comparisons, or compare with a tolerance: abs($a - $b) < 0.0001. Never use == on floats.Interview Questions on This Topic
What is the difference between == and === in PHP, and can you give an example where using == would produce a surprising result?
0 == 'hello' returns true in PHP 7 because 'hello' is converted to 0. Always use === unless you explicitly need coercion.Frequently Asked Questions
That's PHP Basics. Mark it forged?
5 min read · try the examples if you haven't