PHP Secrets: Weird Coding Tricks & Hidden Bugs
Discover mind-blowing PHP quirks, bugs, and security tips that every developer should know. Master safe coding and avoid hidden traps.
1. ‘0e1234’ == ‘0’ returns true (Type Juggling Gotcha)
Why?
PHP converts both strings to floats. '0e1234'
is scientific notation and becomes 0.0
. So '0e1234' == '0'
is true.
Demo:
var_dump('0e1234' == '0'); // true
Correction:
var_dump('0e1234' === '0'); // false
Tip:
Always use ===
for comparing user credentials like hashed passwords.
2. ‘php’ == 0 returns true
Why?
Non-numeric strings become 0
in loose comparisons.
Demo:
var_dump('php' == 0);
Correction:
var_dump('php' === 0); // false
Tip:
Don’t mix types. Avoid ==
between strings and numbers.
3. ‘0’ is falsy but ‘false’ is truthy
Why?
Only '0'
is treated as falsy among non-empty strings.
Demo:
if ('0') echo 'Truthy'; else echo 'Falsy'; // Falsy
if ('false') echo 'Truthy'; else echo 'Falsy'; // Truthy
Correction:
Cast explicitly or check using ===
.
Tip:
Beware when using user inputs like '0'
in conditionals.
4. Leading Zeroes = Octal Confusion
Why?
Numbers starting with 0
are interpreted as octal (base 8).
Demo:
var_dump(010); // int(8)
Correction:
var_dump(10); // int(10)
Tip:
Don’t prefix integers with 0
unless intentional.
5. Loose comparisons with booleans
Why?
PHP coerces types for ==
. 'false' == false
→ 'false'
becomes 0
, false
becomes 0
, so it’s true.
Demo:
var_dump('false' == false); // true
Correction:
var_dump('false' === false); // false
Tip:
Always use strict comparisons.
6. Array keys get overwritten silently
Why?
PHP converts true
, 1
, '1'
all to the same key: 1
.
Demo:
$arr = [true => 'a', 1 => 'b', '1' => 'c'];
print_r($arr); // [1 => 'c']
Correction:
Use distinct string keys.
Tip:
Avoid using booleans or ambiguous values as array keys.
7. Negative string offsets (PHP 7.1+)
Why?
PHP 7.1 added support for negative string indexing.
Demo:
echo 'hello'[-1]; // o
Correction:
Validate length first for compatibility.
Tip:
Great for getting the last character in PHP 7.1+.
8. Floating Point Math Precision
Why?
Binary representation can’t perfectly represent decimal fractions.
Demo:
var_dump((0.1 + 0.7) * 10 == 8); // false
Correction:
var_dump(round((0.1 + 0.7) * 10) == 8); // true
Tip:
Use round()
, bcadd()
or bcmath
functions for money.
9. foreach Affects Array Pointer
Why?
foreach
modifies internal pointer (next()
, current()
).
Demo:
$arr = [1, 2, 3];
foreach ($arr as $v) {}
echo current($arr); // false
Correction:
reset($arr);
Tip:
Use foreach
for iteration only.
10. Dangling references in foreach
Why?
Referenced variable retains reference after loop ends.
Demo:
$arr = [1, 2, 3];
foreach ($arr as &$val) {}
foreach ($arr as $val) {}
print_r($arr); // Last element messed up
Correction:
unset($val);
Tip:
Always unset reference variables after foreach (&$item)
.
11. isset() vs array_key_exists()
Why?
isset()
returns false for null values; array_key_exists()
checks the key only.
Demo:
$a = ['foo' => null];
var_dump(isset($a['foo'])); // false
var_dump(array_key_exists('foo', $a)); // true
Correction:
Use array_key_exists()
when checking key presence.
Tip:
Don’t use isset()
to check if a key exists if values can be null
.
12. Empty Array + Index Assignment Skips Numeric Indexing
Why?
Directly assigning to a numeric index doesn’t auto-increment.
Demo:
$a = [];
$a[5] = 'PHP';
print_r($a); // [5 => 'PHP']
$a[] = 'Dev';
print_r($a); // [5 => 'PHP', 6 => 'Dev']