PHP 5.6 and beyond

Adam Harvey
@LGnome
New Relic

Today

  • PHP 5.3: security fixes only (until July)
  • PHP 5.4: old stable (about to enter security fix only mode)
  • PHP 5.5: stable branch
  • PHP 5.6: in beta
  • ??

PHP release lifecycle

Mar 2012 Jun 2013 Jul 2014 ? 2015 ? 2016 ? 2017 PHP 5.3 PHP 5.4 PHP 5.5 PHP 5.6 PHP ? Supported Security fixes only

PHP 5.3

  • Current release: 5.3.28
  • End of life: July
  • Possibly one more release due to FPM issue already fixed on 5.4 and 5.5

PHP 5.4

  • Current release: 5.4.28
  • Enters security only mode in July
  • Definitely a 5.4.29 coming; maybe a 5.4.30; beyond that further releases as needed

PHP 5.5

  • Current release: 5.5.12
  • Almost halfway through full support phase

PHP 5.5

  • Generators:
    class RangeIterator implements Iterator {
        private $start;
        private $limit;
        private $step;
        private $current;
    
        public function __construct($start, $limit, $step = 1) {
            $this->start = $start;
            $this->limit = $limit;
            $this->step = $step;
            $this->current = $start;
        }
    
        public function current() {
            return $this->current;
        }
    
        public function key() {
            return ($this->current - $this->start) / $this->step;
        }
    
        public function next() {
            $this->current += $this->step;
        }
    
        public function rewind() {
            $this->current = $this->start;
        }
    
        public function valid() {
            return ($this->current >= $this->start && $this->current <= $this->limit);
        }
    }
    
    function xrange($start, $limit, $step = 1) {
        return new RangeIterator($start, $limit, $step);
    }

PHP 5.5

  • Generators:
    function xrange($start, $limit, $step = 1) {
      for ($i = $start; $i <= $limit; $i += $step) {
        yield $i;
      }
    }              

PHP 5.5

  • Finally:
    function do_something() {
      $temp = tempnam('/tmp', 'FOO');
    
      try {
        ...
      } catch (FrameworkException $e) {
        ...
      } finally {
        unlink($temp);
      }
    }

PHP 5.5

  • Password hashing:
    // Creating a hash:
    $hash = password_hash($passwd, PASSWORD_DEFAULT);
    
    // Verifying a password:
    if (password_verify($passwd, $hash)) {
      // do stuff
    }

A brief digression…

  • Password security is hard
  • Don't reinvent the wheel

Which wheel?

  • PHP 5.5's password API: gold
  • password_compat (same API on PHP ≥ 5.3.7): also gold, but tarnished by a minor drug scandal
  • Correct use of crypt in $2y$ bcrypt mode: silver
  • phpass: bronze (best you can do if supporting < 5.3, but it's 2014 now)
  • Plain text/MD5/SHA-1: uhhhhhhh

PHP 5.5

  • OPcache
  • foreach unpacking
  • ::class
  • DateTimeImmutable
  • mysql_* deprecation

Upgrade now!

PHP release lifecycle

Mar 2012 Jun 2013 Jul 2014 ? 2015 ? 2016 ? 2017 PHP 5.3 PHP 5.4 PHP 5.5 PHP 5.6 PHP ? RH 6, Ubu 12.04 RH 7 Deb stable Deb test Ubu 14.04 OS X Supported Security fixes only

Packaging

  • All major distros backport security fixes
  • As long as your system is up to date, you're safe
  • Not so helpful with features

Newer packages

PHP 5.6

  • Currently at beta 3
  • Beta 4 should be out next week
  • July release?
  • 3,617 commits over 5.5 (as of yesterday)
  • 106 individual authors

New features

...

  • In a function declaration, makes the function variadic
  • In a function call, splats parameters

...

function sum() {
  $acc = 0;
  foreach (func_get_args() as $n) {
    $acc += $n;
  }
  return $acc;
}

echo sum(1, 2, 3);
Output:
6

...

function sum(...$params) {
  $acc = 0;
  foreach ($params as $n) {
    $acc += $n;
  }
  return $acc;
}

echo sum(1, 2, 3);
Output:
6

...

function sum(Foo ...$params) {
  $acc = 0;
  foreach ($params as $n) {
    $acc += $n;
  }
  return $acc;
}

echo sum(1, 2, 3);
Output:
Catchable fatal error: Argument 1 passed to sum() must be an instance of Foo, integer given, called in /home/adam/trees/tek-slides/code/variadic-hinted.php on line 11 and defined in /home/adam/trees/tek-slides/code/variadic-hinted.php on line 3

...

function sum() {
  $acc = 0;
  foreach (func_get_args() as $n) {
    $acc += $n;
  }
  return $acc;
}

$input = range(1, 3);
echo call_user_func_array('sum', $input);
Output:
6

...

function sum() {
  $acc = 0;
  foreach (func_get_args() as $n) {
    $acc += $n;
  }
  return $acc;
}

$input = range(1, 3);
echo sum(...$input);
Output:
6

...

function sum(...$params) {
  $acc = 0;
  foreach ($params as $n) {
    $acc += $n;
  }
  return $acc;
}

$input = range(1, 3);
echo sum(...$input);
Output:
6

...

function sum(...$params) {
  $acc = 0;
  foreach ($params as $n) {
    $acc += $n;
  }
  return $acc;
}

echo sum(...range(1, 3));
Output:
6

...

  • Splatting is about 30% faster than call_user_func_array
  • Variadic functions are about the same either way
  • Type hinting variadic arguments may get a very small improvement, but very small

Constant scalar expressions

  • Scalar expressions involving basic arithmetic and concatenation operators can be evaluated at compile time

Constant scalar expressions

const ONE = 1;
const TWO = 2;
const THREE = ONE + TWO;

echo THREE;
Output:
3

Constant scalar expressions

class C {
  const ONE = 1;
  const TWO = 2;
  const THREE = self::ONE + self::TWO;
}

echo C::THREE;
Output:
3

Constant scalar expressions

class C {
  const ONE = 1;
  const TWO = 2;

  function getThreeByDefault($value = self::ONE + self::TWO) {
    return $value;
  }
}

echo (new C)->getThreeByDefault();
Output:
3

Constant scalar expressions

const FOO = [1, 2];
const BAR = FOO[1];

echo BAR;
Output:
2

Constant scalar expressions

  • Array access, string concatenation, +, -, *, /, %, **, !, ~, |, &, ^, <<, >>, xor, and, or, &&, ||, ===, !==, ==, !=, <, >, <=, >=, ? :, ?:, unary +, unary -, parentheses

use

  • use function
  • use const

use

  • use function Name\Space\function_name;
  • use const Name\Space\CONSTANT;

use

  • use function Name\Space\function_name as func;
  • use const Name\Space\CONSTANT as CST;

**

echo 2 ** 3;
Output:
8

phpdbg

  • Integrated, interactive command line debugger

phpdbg

  • Live demo gods: ACTIVATE

Changes

Default charset

  • New configuration variable: default_charset
  • Defaults to UTF-8
  • Used in the Content-Type header
  • Used if no charset is given to htmlentities and friends
  • Also used by iconv and mbstring if specific settings aren't set

Default charset

  • Can be set anywhere
  • On single site setups, just set it in php.ini and be happy
  • Shared environments will need more care

Default charset

  • Does not affect database connections
  • Still need to set charset parameter in PDO

SSL/TLS

  • Peer verification is now on by default
  • Will use OpenSSL's default CA bundle
  • Can be overridden via openssl.cafile or openssl.capath php.ini settings
  • Can be disabled entirely via the verify_peer context option

SSL/TLS

  • SSL/TLS compression is now disabled by default
  • Default ciphers now match the Mozilla recommendations except for removing anonymous Diffie-Hellman and RC4
  • Perfect forward secrecy enabled by default if the server certificate supports it

GMP

  • GMP resources are now objects
  • Function API is unchanged
  • GMP objects support operator overloading

JSON

  • json_decode no longer accepts JSON documents consisting of just a boolean or null literal case insensitively
  • Must use true, false or null
  • Doesn't affect valid JSON

Deprecated features

Calls from incompatible context

class A {
  function f() { echo get_class($this); }
}

class B {
  function f() { A::f(); }
}

(new B)->f();

Raw POST data

  • Access via php://input
  • $HTTP_RAW_POST_DATA will be removed at some point

PHP 5.6

  • Please test it
  • Already available in Homebrew and Remi Collet's CentOS/RHEL repo
  • Please report bugs

The mysterious future

The mysterious future

  • There is no new major version in Git
  • …yet

The mysterious future

  • The next year or two may see a new major version
  • Some changes being proposed are major enough to justify it
  • Even the version number is uncertain!

New versions are scary

  • Many languages have tried major version transitions
  • Varying degrees of success

A quick review

Python 2→3

  • Big cleanup of cruft
  • Some change for change's sake: print()
  • Carefully prepared the userbase with from future import foo

Python 2→3

  • Adoption of Python 3 remains challenging due to ecosystem lock-in
  • Very long term view: maintenance of Python 2 in parallel until at least 2020
  • Ultimately, probably successful, but painful

Ruby 1.9→2

  • Relatively minimal userland changes
  • Older code generally forward compatible with good coding practices
  • Almost a non-event

Perl 5→6

  • lol

Perl 5→6

  • Massive, breaking changes
  • Retconned as a whole new language
  • Zero ecosystem buy in as a result

PHP 4→5

  • Relatively minor BC breaks (pre-5.3)
  • Significant changes to OO
  • Required considerable time and GoPHP5

PHP 5→6 (Unicode)

  • Extensive internal work accepted without full knowledge of scope
  • Scope creep on the userland changes
  • Probably would have been as successful as Perl 6

The challenge

  • PHP has problems
  • (plenty of problems)
  • In a perfect world, a Perl 6 style broom would be nice, but impractical
  • Ideally, you want to make Python 3 cleanups with Ruby 2 impact

How?

  • Userland buy-in is key
  • Breaking changes must be well justified and have a sensible path for code that has to span versions
  • Breaking changes must default to being rejected

Future hazy

  • Expect to see many previously rejected RFCs revived
  • Named arguments?
  • Annotations?
  • Scalar type hints?
  • Your idea here

phpng

  • Major refactor of the Zend Engine
  • Aimed at increasing performance and reducing memory use
  • Developed on a private branch until recently

phpng

  • Looks to be about 20% faster than 5.6 on both synthetic and real world benchmarks
  • Memory usage is down between 20% and 50%, depending on state

phpng

  • Significantly changes internal structures
  • Will have a major impact on many extensions

phpng

  • Still quite some way off
  • Not all core extensions are ported yet
  • Has not yet been through the RFC process
  • Open questions around thread safety

64 bit support

  • Adds support for 64 bit integers and strings on all platforms
  • Originally proposed for PHP 5.6; voted down due to concerns over required extension changes
  • Developed on an open branch
  • Clashes somewhat with phpng

64 bit support

  • Has a performance impact
  • Increases memory usage (by about 4% over phpng)

64 bit support

  • Currently being voted on
  • Was probably a slam dunk before phpng; now somewhat hazy
  • Likely to be a compromise option that ultimately gets accepted rather than 64 bitting all the things

Get involved

  • Now is the time to write an RFC
  • Things tend to go (much) better with working patches

Thank you

  • Questions?