PHP

Wepay

Palo Alto

May 29, 2014

http://talks.php.net/wepay14

Rasmus Lerdorf
@rasmus

PHP 5.5


Performance Improvements

  • Nested calls
  • Call stack pre-allocated by compiler
  • Bundled opcode cache

✔ Generators

function xrange($start, $end) {
    for ($i = $start; $i <= $end; $i ++) {
        yield $i;
    }
}
foreach (xrange(0, 5) as $i) {
    echo $i, "\n";
}

✔ Coroutines

function logger($fileName) {
    $fileHandle = fopen($fileName, 'a');
    while (true) {
        fwrite($fileHandle, yield . "\n");
    }
}

$logger = logger(__DIR__ . '/log');
$logger->send('Foo');
$logger->send('Bar');

For an advanced explanation of coroutines, read this article by Nikita Popov

Cooperative multitasking using coroutines

✔ finally

$db = mysqli_connect();
try {
   call_some_function($db);
} finally {
   mysqli_close($db);
}

✔ list() in foreach

$names = [ ['John','Smith'], ['Fred','Johnson'] ];
foreach($names as list($first,$last)) { 
    echo $first,$last; 
}

✔ Const array/string Dereferencing

echo array(1, 2, 3)[0]; //output 1
echo "foobar"[3]; //output b
echo [1,3,4][2]; //output 4

✔ empty() support for functions/expressions

✔ curl upload functionality rewritten

✔ Simplified password hashing API

// Hash
$hash = password_hash("super secret",PASSWORD_BCRYPT);

// To validate $pwd against the stored hash
if (password_verify($pwd, $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}
php.net/migration55

PHP 5.6


✔ Variadic functions

class MySQL implements DB {
    public function query($query, ...$params) {
        $stmt = $this->pdo->prepare($query);
        $stmt->execute($params);
        return $stmt;
    }
}

$q = 'SELECT * FROM users WHERE id = ?';
$user = $db->query($q, $userID)->fetch();

✔ Argument Unpacking

// A better call_user_func_args
$args1 = [1, 2, 3];
$args2 = [4, 5, 6];
test(...$args1, ...$args2); // [1, 2, 3, 4, 5, 6]
test(1, 2, 3, ...$args2);   // [1, 2, 3, 4, 5, 6]
test(...$args1, 4, 5, 6);   // Fatal error: Cannot use positional argument after argument unpacking

✔ Constant scalar expressions

class Foo {
    const FOO = 1 + 1;
    const BAR = 1 << 1;
    const GREETING = "HELLO";
    const BAZ = self::GREETING." WORLD!"
}

✔ Add right-associative power operator **

echo 2 ** 3 ** 2; // 512 (not 64)
echo -3 ** 2; // -9 (not 9)
echo 1 - 3 ** 2; // -8
echo ~3 ** 2; // -10 (not 16)

✔ Internal operator overloading for internal features like GMP

echo 2**512;
echo "\n";
$n = gmp_init(2);
echo $n**512;
1.3407807929943E+154
13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096
		

✔ use function and use const namespace imports

include 'template.inc';
include 'db.inc';
use function template\header, template\footer, db\query;

header('My Page');
query('select * from stuff');
footer();

✔ default_charset ini now applies to internal funcs

✔ SSL Peer verification by default

✔ openssl certificate fingerprints

✔ SAN x509 ext matching when verifying host names

✔ automatic DoS prevention of TLS renegotiation attacks

✔ and many more openssl-related options

✔ Asynchronous PostgreSQL database connections

✔ Non-blocking PostgreSQL queries

✔ New phpdbg SAPI

✔ Support for > 2GB file uploads

✔ The php://input stream is now re-usable

✔ Added hash_compare() for timing attack safe string comparison

✔ Added gost-crypto (CryptoPro S-box) hash algorithm

✔ FPM workers can now change their apparmor profile

✔ OCI8 Improvements

php.net/migration56

Deploying Web Apps


Are your deploys atomic?

Are you sure?

What happens to a request that is currently executing when you deploy?

Deploying Web Apps


Deploying Web Apps


✔ Don't copy files into current document root

✔ Let existing requests finish on old code

✔ New requests start on new code

✔ Avoid clearing your opcode cache

✔ Minimal impact on production traffic

Deploying Web Apps


Deploying Web Apps


Deploying Web Apps


2 Document Root directories

Symlink /var/www/site toggles between them

realpath() symlink at the web server level

Set Document Root to symlink realpath

Never hardcode the document root in code

Deploying Web Apps


Apache

http://github.com/etsy/mod_realdoc

nginx

You can use $realpath_root

eg. fastcgi_param DOCUMENT_ROOT $realpath_root;

PHP

http://github.com/etsy/incpath

codeascraft.com/2013/07/01/atomic-deploys-at-etsy/