Tutorials Logic, IN info@tutorialslogic.com

PHP Operators: Calculation, Comparison, Defaults, and Precedence

PHP Expression Semantics

PHP operators evaluate expressions under defined precedence, coercion, comparison, null, array, arithmetic, and bitwise rules. Dense syntax can conceal type conversion, short circuiting, and state changes.

Reliable code validates operand types, uses strict comparison, distinguishes nullish from falsy values, documents array merge semantics, and tests numeric and version-migration boundaries.

Arithmetic and Assignment

Operator Meaning Example result
+ Addition 10 + 3 is 13
- Subtraction 10 - 3 is 7
* Multiplication 10 * 3 is 30
/ Division 10 / 4 is 2.5
% Remainder 10 % 3 is 1
** Exponentiation 2 ** 3 is 8
+= Update by addition $count += 2

Cart Total

Cart Total
<?php
$unitPrice = 249.50;
$quantity = 2;
$discount = 50.00;
$total = ($unitPrice * $quantity) - $discount;

echo number_format($total, 2);
Output
449.00

Strict Comparison

The == operator allows type conversion before comparison. The === operator requires the same type and value. Strict comparison makes values such as 0, false, null, and an empty string easier to reason about.

Use !== when both a different type and a different value should count as unequal.

Zero Is Not Missing

Zero Is Not Missing
<?php
$position = array_search('PHP', ['HTML', 'PHP', 'SQL'], true);

if ($position === false) {
    echo 'Not found';
} else {
    echo "Found at index {$position}";
}
Output
Found at index 1

array_search() can return index 0, so a strict false check is required.

Logical Operators

&& and || short-circuit: PHP stops once the final result is known. Put cheap safety checks before operations that require valid data.

Readable Access Rule

Readable Access Rule
<?php
$isSignedIn = true;
$role = 'editor';
$canEdit = $isSignedIn && ($role === 'editor' || $role === 'admin');

echo $canEdit ? 'Edit allowed' : 'Read only';
Output
Edit allowed

Defaults and Ordering

Use ?? for a missing or null value, ??= to assign such a default, and <=> when a sorting callback needs -1, 0, or 1.

Default and Sort

Default and Sort
<?php
$query = [];
$page = $query['page'] ?? 1;
$scores = [82, 95, 76];
usort($scores, fn (int $a, int $b): int => $b <=> $a);

echo "Page {$page}: " . implode(', ', $scores);
Output
Page 1: 95, 82, 76

Precedence Traps

  • Use parentheses around mixed && and || conditions.
  • Do not assign inside a condition unless the reason is obvious and tested.
  • Remember that string concatenation uses . rather than +.
  • Avoid relying on truthiness when an API returns a valid zero or empty string.

Precedence and Evaluation

Operator precedence decides grouping, and associativity decides grouping among operators at the same level. It does not guarantee a convenient order for every side effect. Parenthesize mixed expressions and keep assignments or function calls with side effects out of dense conditions.

The low-precedence word operators `and`, `or`, and `xor` do not group like `&&` and `||`. An assignment combined with `and` can assign before the logical operation, producing a surprising value. Prefer symbolic logical operators in expressions and reserve word forms for code whose grouping is unmistakable.

String concatenation uses `.` and concatenation assignment uses `.=`. In modern PHP, concatenation precedence relative to arithmetic changed from older versions, so code migrated from legacy PHP should use parentheses when combining strings and calculations.

An expression returns a value, including assignments and comparisons. Avoid chained assignment in application logic when it hides which variables are declared or updated. One explicit statement per state transition is easier to debug.

  • Use parentheses for mixed operator families.
  • Do not interchange word and symbolic logical operators casually.
  • Review concatenation with arithmetic during legacy migration.
  • Keep state-changing assignments visible.

Comparison Semantics

`===` and `!==` compare type and value without loose conversion. Use them for most application decisions. Loose equality has detailed type-juggling rules that can make numeric strings, booleans, null, and numbers compare unexpectedly, especially at external input boundaries.

The spaceship operator `<=>` returns a negative value, zero, or a positive value and is useful in sorting callbacks. Compose comparisons only after normalizing case, locale, numeric representation, null policy, and tie breakers. A stable domain order needs more than one operator.

Object identity with `===` requires the same instance. Object equality with `==` compares properties under PHP rules and can recurse through structure. Prefer domain identifiers or explicit value-object equality so the intended fields are visible and controlled.

Floating-point calculations cannot represent every decimal exactly. Compare measured values with a domain tolerance and represent exact money in integer minor units or a suitable decimal facility. Do not repair precision with string comparison.

  • Use strict comparison at application boundaries.
  • Normalize values before sorting with spaceship.
  • Define object equality through domain identity or value fields.
  • Choose numeric representation from precision requirements.

Null and Conditional Operators

The null coalescing operator `??` selects the right operand only when the left value is missing or null, without producing an undefined-key notice for supported access forms. It preserves zero, false, and empty string, unlike the shorthand ternary form based on truthiness.

Null coalescing assignment `??=` initializes only a missing or null variable or property. Use it for a valid lazy default, not to manufacture an empty domain object when null represents unauthenticated, deleted, or unavailable state.

The nullsafe operator `?->` stops a method or property chain when its receiver is null and returns null for the chain. It is read-only and does not suppress exceptions or invalid non-null types. Use it only where each nullable link is intentional.

The ternary operator expresses one value choice. Nesting unparenthesized ternaries is not supported in modern PHP because intent is ambiguous. Use `match`, a named function, or explicit branches when decisions multiply.

  • Use null coalescing when falsy values remain valid.
  • Initialize nullish state only through valid transitions.
  • Treat nullsafe access as optionality, not validation.
  • Replace nested ternaries with clearer decision structures.

Array Operators

The array union operator `+` keeps keys from the left array and adds only keys not already present from the right. It is not concatenation and can discard right-side numeric positions that collide. Use `array_merge` or a domain-specific merge when replacement or reindexing semantics are required.

Array equality `==` compares key-value pairs without requiring the same order or strict value types under all cases, while identity `===` requires the same key order and strict key-value types. Choose the comparison that matches the data contract and normalize externally parsed values first.

Compound assignment on an array element still performs lookup, operation, and write under PHP rules. Check key existence and expected type before arithmetic or concatenation. Missing keys and mixed data should fail at validation rather than creating notices deep in a calculation.

Spread syntax in arrays has version-specific key behavior and is distinct from the union operator. For application merges, document duplicate-key policy, numeric reindexing, and whether nested arrays are copied shallowly or merged recursively.

  • Do not confuse array union with concatenation.
  • Choose equality or identity from order and type requirements.
  • Validate array element existence before compound assignment.
  • Document duplicate-key and nesting policy for merges.

Arithmetic and Bitwise Boundaries

Arithmetic operands must satisfy numeric rules, and malformed numeric strings can warn or fail depending on the operation and PHP version. Validate external numbers explicitly, reject trailing text, enforce ranges, and preserve the original field name in an error message.

Division uses `/`, integer division uses `intdiv`, and remainder uses `%`. Division by zero and integer-division edge cases raise errors that belong in input validation or a deliberate exception boundary. Negative remainder behavior should be tested when implementing cyclic indexes.

Bitwise operators act on integers or, for certain operations, strings under specific rules. They are appropriate for flags and binary protocols with documented widths. Do not use them as clever boolean operators; `&` and `|` do not short circuit.

Increment and decrement have special behavior across types and should not be used as generic conversion tools. Keep counters numeric and typed. Use explicit date, string, or enum transitions rather than relying on implicit cross-type increment behavior.

  • Validate numeric input before arithmetic.
  • Handle division and remainder edge cases explicitly.
  • Reserve bitwise operations for defined binary representations.
  • Keep increment and decrement on intentional counters.

Operator Tests and Review

Test zero, negative values, numeric strings, empty input, null, false, boundary integers, floating-point cases, duplicate array keys, missing keys, and mixed types according to the function contract. Include one case on each side of every comparison boundary.

Static analysis can flag impossible comparisons, mixed operands, undefined offsets, and suspicious boolean expressions. Configure a target PHP version so analysis and syntax rules match production. Formatting cannot prove that an expression groups as the author intended.

During review, ask what types each operand can have, what conversion occurs, whether the right side may be skipped, what side effect is triggered, and whether order is visible. Split an expression when those answers require a paragraph.

For a legacy upgrade, run tests under the new runtime and search for nested ternaries, word logical operators around assignment, string-number coercion, concatenation mixed with arithmetic, and weak comparisons at request or database boundaries.

  • Cover type and numeric boundaries in tests.
  • Align static analysis with production PHP.
  • Make conversions, short circuiting, and side effects reviewable.
  • Audit legacy expressions during runtime upgrades.
Before you move on

Mastery Check

7 checks
  • Parenthesize mixed operator families.
  • Use strict comparisons at data boundaries.
  • Preserve valid falsy values with null-aware operators.
  • Choose array union or merge from duplicate-key policy.
  • Test coercion, division, precision, and missing-key cases.
  • Trace operand types and evaluation order before simplifying a dense expression.
  • Verify right-hand side effects are intentionally skipped by short-circuit operators.

Operator Choices

0 of 2 checked

Q1. Which comparison distinguishes 0 from false?

Q2. When does $value ?? $default use the default?

Operator Boundary

  • Loose comparison

    Type juggling in == can equate values from different domains. Normalize input and prefer strict comparison unless coercion is explicitly part of the rule.

Try this next

Test Operator Boundaries

0 of 2 completed

  1. Grant free shipping only when a user is a member and the order is at least 500, or when a valid promotion is active. Use parentheses.
  2. Sort three associative arrays by score descending with the spaceship operator.
Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.