Tuesday, January 26, 2016

Crazy PHP, a collection of phenomenons and common mistakes

Oftentimes PHP is like Java, but in many cases, it's not. In this article I'm trying to collect some examples of paranormal behavior of PHP code.

1. Array keys

$arr = [];
$arr['123'] = 1;
$arr[123] = 2;
$arr[123.1] = 3;
$arr[123.0] = 4;
$arr[123.00001] = 5;
$arr[123.999999999999999] = 6;
$arr['123.0'] = 7;
$arr[null] = 8;
$arr[] = 9;

print_r($arr);
gives:
Array
(
    [123] => 5
    [124] => 6
    [123.0] => 7
    [] => 8
    [125] => 9
)

2. Casting

echo (int)'21 - Adele';       // 21
echo (int)'2 fast 2 furious'; // 2
echo (int)'-273.65';          // -273
echo (int)'-273';             // -273
echo (int)'19. Januar 2011';  // 19
var_dump((bool)'0');          // bool(false)
var_dump((bool)'0.0');        // bool(true)
var_dump((bool)'-1');         // bool(true)
var_dump((bool)-1);           // bool(true)
var_dump((bool)[]);           // bool(false)
var_dump((bool)new stdclass); // bool(true)
echo ['foo'];                 // Array

3. Switch

switch (1) {
    case null: echo 'a'; break;
    case '1': echo 'b'; break;
    case '0': echo 'c'; break;
}

// gives: b

switch('2string') {
    case 1: echo 'a'; break;
    case 2: echo 'b'; break;
    case '2string': echo 'c'; break;
}

// gives: b

$x = true;
$y = false;
switch (true) {
    case ($x != 1): echo 'a'; break;
    case ($y != null): echo 'b'; break;
    default: echo 'c'; break;
}

// gives: c

4. Array merging

print_r([1, 2] + [3, 4]);             // [1, 2]
print_r(array_merge([1, 2], [3, 4])); // [1, 2, 3, 4]

5. Empty

echo (int)empty('0');   // 1
echo (int)empty('0.0'); // 0
echo (int)empty(0);     // 1
echo (int)empty(0.0);   // 1

6. In_array

echo (int)in_array(0, ['a']);           // 1
echo (int)in_array('a', [0]);           // 1
echo (int)in_array(0.0, ['a']);         // 1
echo (int)in_array('21 - Adele', [21]); // 1
echo (int)in_array(42, ['42.0']);       // 1
echo (int)in_array(42, ['42.1']);       // 0

// Note: oftentimes integers come from SOAP calls, json_decode(), curl_getinfo(), etc.

7. Htmlspecialchars / Htmlentities

<?php $xss = "');document.write('Hello!');//"; ?>
<html>
<body onload="alert('<?= htmlspecialchars($xss); ?>')"></body> <!-- output: Hello! -->
</html>

// Note: json_encode() is your friend to put content inside Javascript code

8. Comparison

var_dump(0 == 'a');          // bool(true)
var_dump('1' == '01');       // bool(true)
var_dump('1' == '1.0');      // bool(true)
var_dump([] < new stdclass); // bool(true)
var_dump(10 <= true);        // bool(true)
var_dump('' == null);        // bool(true)

max(0, false); // 0
max(false, 0); // false

echo null ?: [] ?: 0 ?: 1 ?: 2; // 1
echo 1 ? 2 : 3 ? 4 : 0; // 4

$d1 = new DateTime("2016-01-01 10:00:00.000000");
$d2 = new DateTime("2016-01-01 10:00:00.889342");
var_dump($d1 == $d2); // bool(true)

See the official documentation for the rules that are applied.

9. Date calculations

echo date('Y-m-d', strtotime('2015-12-31 previous month')); // 2015-12-01
echo date('Y-m-d', strtotime('2015-01-31 next month'));     // 2015-03-03

2 comments:

  1. What exactly is a phenomenon here? Well known documented behavior.

    ReplyDelete
    Replies
    1. yes well documented, just let 5 developers predict the results without using the interpreter :)

      Delete

Labels

performance (23) benchmark (6) MySQL (5) architecture (5) coding style (5) memory usage (5) HHVM (4) C++ (3) Java (3) Javascript (3) MVC (3) SQL (3) abstraction layer (3) framework (3) maintenance (3) Go (2) Golang (2) HTML5 (2) ORM (2) PDF (2) Slim (2) Symfony (2) Zend Framework (2) Zephir (2) firewall (2) log files (2) loops (2) quality (2) real-time (2) scrum (2) streaming (2) AOP (1) Apache (1) Arrays (1) C (1) DDoS (1) Deployment (1) DoS (1) Dropbox (1) HTML to PDF (1) HipHop (1) OCR (1) OOP (1) Objects (1) PDO (1) PHP extension (1) PhantomJS (1) SPL (1) SQLite (1) Server-Sent Events (1) Silex (1) Smarty (1) SplFixedArray (1) Unicode (1) V8 (1) analytics (1) annotations (1) apc (1) archiving (1) autoloading (1) awk (1) caching (1) code quality (1) column store (1) common mistakes (1) configuration (1) controller (1) decisions (1) design patterns (1) disk space (1) dynamic routing (1) file cache (1) garbage collector (1) good developer (1) html2pdf (1) internationalization (1) invoice (1) just-in-time compiler (1) kiss (1) knockd (1) legacy code (1) legacy systems (1) logtop (1) memcache (1) memcached (1) micro framework (1) ncat (1) node.js (1) openssh (1) pfff (1) php7 (1) phpng (1) procedure models (1) ramdisk (1) recursion (1) refactoring (1) references (1) regular expressions (1) search (1) security (1) sgrep (1) shm (1) sorting (1) spatch (1) ssh (1) strange behavior (1) swig (1) template engine (1) threads (1) translation (1) ubuntu (1) ufw (1) web server (1) whois (1)