Operator Precedence and Associativity

Which operator binds first, why ** is right-associative, and how a stray precedence assumption becomes a real bug.

Precedence decides who grabs the operands first; associativity breaks ties among equal operators. You don't need to memorise the whole table — you need to know the handful that bite.

The ones that catch people

  • ** is right-associative and higher than unary minus: -3 ** 2 is -9.
  • && binds tighter than ||: a || b && c means a || (b && c).
  • The word forms and/or bind looser than = — a classic assignment surprise.
  • Concatenation . now binds looser than +/- (changed in PHP 8), so "sum: " . 1 + 2 parses as "sum: " . (1 + 2).

Easy example

<?php
var_dump(2 + 3 * 4);   // 14, not 20
var_dump(2 ** 3 ** 2); // 512, right-associative
var_dump(true || false && false); // true

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Parenthesise a bitwise OR expression inside an if condition to prevent it being mistaken for logical OR.
  • Use explicit parentheses around arithmetic in a complex discount formula to document intended calculation order.
  • Rely on knowing ** is right-associative to write clean repeated-power expressions without extra variables.

More examples

Precedence changes the result

* has higher precedence than +; ** is right-associative — parentheses make the intended order explicit and safe.

Example · php
<?php
$a = 2 + 3 * 4;       // 14: * before +
$b = (2 + 3) * 4;     // 20: parentheses first

$c = 2 ** 3 ** 2;     // 512: right-assoc: 2**(3**2)=2**9
$d = (2 ** 3) ** 2;   // 64:  left first

echo "$a $b $c $d";

Boolean vs bitwise confusion

Mixing | (bitwise OR) with || (logical OR) is a common precedence confusion; use parentheses and the right operator.

Example · php
<?php
$perm  = 6;  // binary 110
$read  = 1;  // 001
$write = 2;  // 010

// Bug: || returns true/false, not the bit result
if ($perm || $write) { echo 'wrong'; }

// Correct: use & for bitwise AND check
if ($perm & $write) { echo 'has write'; }

Complex expression with parens

Explicit parentheses communicate the intended order and prevent subtle precedence bugs in multi-step formulas.

Example · php
<?php
$price    = 100;
$discount = 0.1;
$tax      = 0.08;

// Without parens: wrong order
$bad  = $price - $price * $discount + $tax * $price;

// With parens: clear intent
$good = ($price * (1 - $discount)) * (1 + $tax);

echo round($bad,  2); // 98.0 (wrong)
echo round($good, 2); // 97.2 (correct)

Discussion

  • Be the first to comment on this lesson.