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'); // trueCorrection:
var_dump('0e1234' === '0'); // falseTip:
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); // falseTip:
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'; // TruthyCorrection:
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); // trueCorrection:
var_dump('false' === false); // falseTip:
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]; // oCorrection:
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); // falseCorrection:
var_dump(round((0.1 + 0.7) * 10) == 8); // trueTip:
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); // falseCorrection:
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 upCorrection:
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)); // trueCorrection:
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']