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']

Tip: Index starts from highest numeric key + 1 when using $a[].