PHP 7 is (almost) here

OMG! PANIC!

Adam Harvey
@LGnome
New Relic

It's faster

It's better

43 RFCs

9,054 commits (and counting)

PHP 5.6 is EOL on
August 28, 2017

PHP < 7 is EOL on
August 28, 2017

(that's in 2 years, 3 months, 7 days)

Distribution packages

Ubuntu 14.04: PHP 5.5.9, supported to 4/2019

RHEL 7: PHP 5.4.16, supported to 6/2024

BC theory

Old & broken New & shiny Libraries

BC theory

Old & broken New & shiny Libraries

Library authors

Library users

(also known as everyone)

Testing

Tooling

Try it!

Variable handling

Indirect references


$$foo['bar']['baz']
$foo->$bar['baz']
$foo->$bar['baz']()
Foo::$bar['baz']()
            

Why?


$foo()['bar']()
$foo::$bar::$baz
Foo::bar()()
(function() { ... })()
($obj->closure)()
[$obj, 'method']()
            

$$foo['bar']['baz'];
            

in PHP 5:


${$foo['bar']['baz']};
            

$$foo['bar']['baz'];
            

in PHP 7:


($$foo)['bar']['baz'];
            

$foo->$bar['baz']
            

in PHP 5:


$foo->{$bar['baz']}
            

$foo->$bar['baz']
            

in PHP 7:


($foo->$bar)['baz']
            

Foo::$bar['baz']()
            

in PHP 5:


Foo::{$bar['baz']}()
            

Foo::$bar['baz']()
            

in PHP 7:


(Foo::$bar)['baz']()
            

What do I do?


Foo::$bar['baz']()
            

Foo::$bar['baz']()
            

Using curly braces:


Foo::{$bar['baz']}()
            

Foo::$bar['baz']()
            

Break it down:


$method = $bar['baz'];
Foo::$method();
            

What do I look for?

IDEs


git grep -E '((((::)|(->))\$[a-zA-Z_][a-zA-Z0-9_]*)+\[[^\s]+\]\())|(->\$[a-zA-Z_][a-zA-Z0-9_]*\[)|(\$\$[a-zA-Z_][a-zA-Z0-9_]*\[)'
            

or with GNU grep:


grep -E '((((::)|(->))\$[a-zA-Z_][a-zA-Z0-9_]*)+\[[^\s]+\]\(\))|(->\$[a-zA-Z_][a-zA-Z0-9_]*\[)|(\$\$[a-zA-Z_][a-zA-Z0-9_]*\[)'
            

Engine exceptions

PHP 5

E_ERROR: 182
E_RECOVERABLE_ERROR: 17
E_PARSE: 1

PHP 7

E_ERROR: 54 (-128)
E_RECOVERABLE_ERROR: 3 (-14)
E_PARSE: 0 (-1)


function square(int $n): int {
  return $n * $n;
}

square('foo');
            

Fatal error: Uncaught TypeError:
Argument 1 passed to square() must
be of the type integer, string given
            

try {
  square('foo');
} catch (TypeError $e) {
  // Recover gracefully.
  // (or show a graceful error)
}
            

PHP 5


Exception
  LogicException
  RuntimeException
            

PHP 7


Throwable
  Error
    ParseError
    TypeError
  Exception
    LogicException
    RuntimeException
            

try {
  ...
} catch (Exception $e) {
  // Catch almost everything?
}
            

try {
  ...
} catch (Throwable $e) {
  // Catch everything, but is
  // that a good idea?
}
            

What do I do?

set_exception_handler

PHP 5

Errors set_error_handler Exceptions catch (Exception $e)

PHP 7

Errors set_error_handler Exceptions Error set_exception_handler Exception catch (Exception $e)

try {
  $code = '<?php echo 01090; ?>';
  highlight_string($code);
} catch (ParseError $e) {
  ...
}
            

Today


function log_exc(Exception $e) {
  ...
}

set_exception_handler('log_exc');
            

PHP 7 only


function log_exc(Throwable $e) {
  ...
}

set_exception_handler('log_exc');
            

PHP 5 and 7


function log_exc($e) {
  ...
}

set_exception_handler('log_exc');
            

What do I look for?

git grep set_exception_handler
git grep -E 'catch\s*\(\\?Exception\s'

foreach

(there are two)


$a = [1];
foreach ($a as &$v) {
  if ($v == 1) $a[] = 2;
  var_dump($v);
}
            

PHP 5:


int(1)
            

$a = [1];
foreach ($a as &$v) {
  if ($v == 1) $a[] = 2;
  var_dump($v);
}
            

PHP 7:


int(1)
int(2)
            

reset()
key()
current()
end()
next()
prev()
pos()


$a = range(1, 3);
foreach ($a as &$v) {
  var_dump(current($a));
}
            

PHP 5:


int(2)
int(3)
bool(false)
            

$a = range(1, 3);
foreach ($a as &$v) {
  var_dump(current($a));
}
            

PHP 7:


int(1)
int(1)
int(1)
            

What do I do?

Don't use the old array iteration functions

Use array_walk or array_map


array_walk($a, function (&$v, $k) {
  ...
});
            

$a = array_map(function ($v) {
  ...
}, $a);
            

Refactor

What do I look for?


git grep -E 'foreach.*\sas\s+&'
            

Hex strings are no longer numeric


function square($n) {
  return $n * $n;
}

echo square("0x10");
            

PHP 5:


  256
            

function square($n) {
  return $n * $n;
}

echo square("0x10");
            

PHP 7:


0
            

What do I do?


$n = sscanf('0x10', '%x')[0];
echo square($n);
            

What do I look for?

¯\_(ツ)_/¯

list() fails silently with string input


$s = 'abc';
list($a, $b, $c) = $s;
var_dump($a, $b, $c);
            

PHP 5:


string(1) "a"
string(1) "b"
string(1) "c"
            

$s = 'abc';
list($a, $b, $c) = $s;
var_dump($a, $b, $c);
            

PHP 7:


NULL
NULL
NULL
            

What do I do?


list($a, $b, $c) = str_split($s);
            

What do I look for?

yield


yield $foo or $bar;
            

in PHP 5:


yield ($foo or $bar);
            

yield $foo or $bar;
            

in PHP 7:


(yield $foo) or $bar;
            

What do I do?

What do I look for?

Sorting


$a = ['o', 'O'];
$opt = SORT_STRING|SORT_FLAG_CASE;
sort($a, $opt);

echo json_encode($a);
            

in PHP 5:


["O","o"]
            

$a = ['o', 'O'];
$opt = SORT_STRING|SORT_FLAG_CASE;
sort($a, $opt);

echo json_encode($a);
            

in PHP 7:


["o","O"]
            

What do I do?

What do I look for?

date.timezone

PHP 5


DateTime::__construct(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function.
...
            

PHP 7


            

bool
int
float
string
null
false
true
resource
object
mixed
numeric


$HTTP_RAW_POST_DATA
            

becomes:


file_get_contents('php://input');
            

ext/mysql is gone

(really)


function f() {
  global $$foo->bar;
}
            

Zend repos

Rasmus's (slightly out of date) php7dev Vagrant image

Questions?

http://joind.in/13745

https://lawngnome.github.io/php7-omg-panic/

@LGnome

Image credits

PHP7: Vincent Pontier

Panic: wackystuff (CC-BY-SA 2.0)

Don't panic: Jim Linwood (CC-BY-SA 2.0)

Head in sand: Peter (CC-BY-SA 2.0)

Flag day: Seattle Municipal Archives (CC-BY 2.0)

Dual wield: Joriel Jimenez (CC-BY 2.0)

What do?: Ian Sane (CC-BY 2.0)

Strategy: Horia Varlan (CC-BY 2.0)

The Scream: Edvard Munch (PD)

Sun stone: Michael McCarty (CC-BY 2.0)

Yesterday: Star Trek

Wrenches: LadyDragonflyCC - >;< (CC-BY 2.0)

Soon: k rupp (CC-BY 2.0)