Skip to main content
PHP7 is coming
in November 2015
Hello
 Julien PAULI
 PHP user for more than 10y now
 Linux / Unix adopter
 PHP Internals developper (C language)
 PHP 5.5 / 5.6 Release Manager
 Working at SensioLabs (Paris)
 Likes writing tech articles/books
 @julienpauli - jpauli@php.net
 Blog at http://jpauli.github.io
PHP versions ?
 PHP 5.3
 Dead
 PHP 5.4
 Dead
 PHP 5.5
 Dead (sec fixes only)
 PHP 5.6
 Current version (Sept 2014), still current
 PHP 7
 Future version (end 2015)
 Major version
 PHP 8
 2020 ?
Timeline
 http://php.net/supported-versions.php
2004 2015
5.0 PHP 7.0
2005 2006 2009
5.1 5.2 5.3 5.4
2012 2013 2014
5.5 5.6
PHP 6 ?
PHP 6 ?
PHP 7
PHP 7
PHP 7 doctrines
 We are in a new major, we may break things
 Only majors are allowed to do so (starting from 5.4)
 We are devs. we also need to refactor (like you)
 Only break when it brings a significant advantage
 Think about our users and their migrations
 Do not fall into a Python2 vs Python3 war
 We'll have PHP 7.1 etc.. and PHP 8.0, probably in 2020.
So ?
 Functions arguments order will not be touched
 Functions() won't be turned into objects->methods()
 "Goto" will not disappear
 And the earth won't just stop its rotation tomorrow
PHP 7 changes
 Internal Engine evolutions (Zend Engine 3.0)
 Perfs ++
 32/64bits platform fully supported
 Integer sizes
 New parser based on an AST
 Some syntaxes change with PHP5
 Tidy up old things that were deprecated before
 Many new features
PHP7 new user features
 Exceptions to replace fatal errors
 New language syntaxes
 ?? operator
 <=> operator
 Group use
 Return type declaration and scalar type hints
 Anonymous classes
 Other new features (Can't list all here)
PHP 7 new features
PHP 7 group "use" decl.
 Group "use" declaration :
use SymfonyComponentConsoleHelperTable;
use SymfonyComponentConsoleInputArrayInput;
use SymfonyComponentConsoleInputInputInterface;
use SymfonyComponentConsoleOutputOutputInterface;
use SymfonyComponentConsoleQuestionChoiceQuestion as Choice;
use SymfonyComponentConsoleQuestionConfirmationQuestion;
use SymfonyComponentConsole{
HelperTable,
InputArrayInput,
InputInputInterface,
OutputOutputInterface,
QuestionChoiceQuestion as Choice,
QuestionConfirmationQuestion,
};
PHP 7 ?? operator
 ?? : Null Coalesce Operator
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
$username = $_GET['user'] ?? 'nobody';
PHP 7 <=> operator
 Combined Comparison (Spaceship) Operator
 (expr) <=> (expr) returns 0 if both operands are
equal, -1 if the left is greater, and 1 if the right is
greater
function order_func($a, $b) {
return ($a < $b) ? -1 : (($a > $b) ? 1 : 0);
}
function order_func($a, $b) {
return $a <=> $b;
}
PHP7 Errors and Exceptions
PHP7 Exceptions instead of fatals
 The engine allows the user to try{}catch{} any call that
may generate a fatal error
 Every other error stays untouched, only fatals can now
be caught
 E_RECOVERABLE are turned to exceptions (most of
them)
 There is no more need to hack with user error handlers,
just try-catch now
 E_STRICT have been reclassified to E_WARN or E_NOTICE
PHP7 Exceptions instead of fatals
 The engine now allows the user to try{}catch{} any
call that may generate a fatal error
foo();
try {
foo();
} catch (Error $e) {
/* haha */
}
PHP7 Exceptions instead of fatals
 If the user doesn't catch the engine exception, this
latter is back converted to a Fatal Error
foo();
Fatal error: Uncaught Error: Call to undefined function foo()
in /tmp/foo.php:2
Stack trace:
#0 {main}
thrown in /tmp/foo.php on line 2
PHP7 Exceptions instead of fatals
 Some parse errors are catchable (ParseException),
especially using eval();
try {
$result = eval($code);
} catch (ParseException $exception) {
}
PHP7 Exceptions instead of fatals
PHP7 Exceptions instead of fatals
 PHP errors inherit from Error
 User exceptions inherit from Exception (no change)
 To catch both, you may catch Throwable
 Users can't inherit from Throwable directly
try {
foo();
} catch (Throwable $e) {
/* catch any user defined Exception
or catch any fatal Error */
}
PHP7 Closures
 Closure::call(object $to, [mixed ...$params])
 Allows to bind a Closure to a specific object at
runtime
 Won't work for internal classes : user classes only
class Foo { public $bar; }
$foo = new Foo;
$foo->bar = 3;
$foobar = function ($qux) { var_dump($this->bar + $qux); };
$foobar->call($foo, 4); /* int(7) */
PHP7 return type declaration
 Functions may declare return types.
 Types "null" and "resource" are not supported
 Those are checked at runtime issuing Fatal errors
function foo(): int {
return [];
}
foo();
Fatal error: Return value of foo() must be of the
type integer, array returned
PHP7 return type declaration
 Functions may declare return types
 Types "null" and "resource" are not supported
 PHP will try to convert them when possible, if not, it
issues a fatal error
function foo($i): int {
return $i;
}
var_dump(foo("123"));
(int)123
var_dump(foo( ["123"] ));
Fatal error: Return value of foo() must be of
the type integer, array returned
PHP7 return type declaration
 Call time variance type is allowed
interface A {
static function make(): A;
}
class B implements A {
static function make(): A {
return new B();
}
}
PHP7 return type declaration
 Compile time variance type is not allowed
interface A {
static function make(): A;
}
class B implements A {
static function make(): B {
return new B();
}
}
Fatal error: Declaration of B::make() must
be compatible with A::make(): A
PHP7 scalar type hints
 Scalar type hints are now allowed in functions arguments
declarations
 Type "null" and "resource" are not supported
 https://wiki.php.net/rfc/scalar_type_hints_v5
function foo(int $i, string $j, bool $k) { }
PHP7 scalar type hints
 By default, scalar type hints are not honored
 The default behavior is that PHP ignores those scalar
type hints, but not compound ones (like it used to
do)
function foo(int $i, string $j, bool $k) { }
foo(1, 1, 1); /* OK */
function foo(int $i, array $j) { }
foo('baz', 'bar');
Fatal error: Argument 2 passed to foo()
must be of the type array, string given
PHP7 scalar type hints
 PHP converts the scalar type hinted arguments
function foo(int $i, string $j, bool $k)
{
var_dump(func_get_args());
}
foo('12', 0, 'foo');
array(3) {
[0]=>
int(12)
[1]=>
string(1) "0"
[2]=>
bool(true)
}
PHP7 scalar type hints
 PHP converts the scalar type hinted arguments, only
when this is possible , if not, it emits a fatal error
function foo(int $i, string $j, bool $k)
{
var_dump(func_get_args());
}
foo('foo', 0, 'foo');
Fatal error: Argument 1 passed to foo() must
be of the type integer, string given
PHP7 scalar type hints errors
 As Fatal Errors may now be catched, this can be
used : function foo(int $i, string $j, bool $k)
{
var_dump(func_get_args());
}
try {
foo('foo', 0, 'foo');
} catch (TypeError $e) {
echo $e->getMessage();
}
Fatal error: Argument 1 passed to foo() must
be of the type integer, string given
PHP7 scalar type hints
 PHP however allows you to declare strict type hints
 honored for every future call
 no implicit conversion anymore
 strict checks must be turned on at function call-time
 strick checks are file-bound (not global)
 declare() must be the first file statement
function foo(int $i, string $j, bool $k) { }
foo(1, 'foo', true); /* OK */
declare(strict_types=1);
foo('1', 'foo', 'baz'); /* fatal */
PHP7 scalar type hints
 strict mode is also relevant for return type hints :
function foo(int $i) :string { return $i; }
var_dump(foo("123 pigs"));
string(3) "123"
declare(strict_types=1);
var_dump(foo(123));
Fatal error: Return value of foo() must be
of the type string, integer returned
PHP 7 new type hints
 Scalar type hints and return types are independant
features, one may be used without the other
 However, they are both affected by the strict mode
 Strict mode is file based only, it doesn't affect other
required files
 Strict mode is disabled by default
 Strict mode may be turned on for every function
calls, it doesn't impact function declarations at all
Anonymous classes
 Like anonymous functions
var_dump( new class() { });
object(class@anonymous)#1 (0) {
}
Anonymous classes
 Like anonymous functions
$obj->setLogger(new class implements Logger {
public function log($msg) {
print_r($msg);
}
});
interface Logger { function log($m); }
class Bar { function setLogger(Logger $l) { } }
$obj = new Bar;
PHP 7 new minor features
 Added scanner mode INI_SCANNER_TYPED to yield typed .ini
values
 Added second parameter for unserialize() function allowing to
specify acceptable classes
 preg_replace_callback_array()
 intdiv()
 error_clear_last()
 PHP_INT_MIN
 random_bytes()
 New assertion mechanism (more optimized, useful)
 New session features (lazy writes, , read only ...)
PHP 7 breakages
PHP 7 breakage
 Syntax changes that break
 Removals
 Behavior changes
PHP 7 Syntax changes
 The compiler has been rewritten entirely
 It is now based on an AST
 You may use the AST using
https://github.com/nikic/php-ast extension
 Some syntax changes were necessary to support new
features
PHP 7 Syntax changes
 Indirect variable, property and method references are
now interpreted with left-to-right semantics
$$foo['bar']['baz']
$foo->$bar['baz']
$foo->$bar['baz']()
Foo::$bar['baz']()
($$foo)['bar']['baz']
($foo->$bar)['baz']
($foo->$bar)['baz']()
(Foo::$bar)['baz']()
${$foo['bar']['baz']}
$foo->{$bar['baz']}
$foo->{$bar['baz']}()
Foo::{$bar['baz']}()
In PHP5
PHP 7 Syntax changes
 list() allows ArrayAccess objects (everytime)
 list() doesn't allow unpacking strings anymore
 Other minor changes to list() ...
list($a, $b) = (object) new ArrayObject([0, 1]);
/* $a == 0 and $b == 1 */
$str = "xy";
list($x, $y) = $str;
/* $x == null and $y == null */
/* no error */
PHP 7 Syntax changes
 Invalid octal literals (containing digits > 7) now
produce compile errors
 Hexadecimal strings are not recognized anymore
$i = 0781; // 8 is not a valid octal digit!
/* Fatal error: Invalid numeric literal in */
var_dump("0x123" == "291");
var_dump(is_numeric("0x123"));
var_dump("0xe" + "0x1");
bool(false)
bool (false)
int(0)
bool(true)
bool(true)
int(16)
In PHP5In PHP7
PHP 7 Syntax changes
 The new UTF-8 escape character u has been added
 Only added in heredocs and double-quoted strings
(as usual)
 Codepoints above U+10FFFF generate an error
 https://wiki.php.net/rfc/unicode_escape
echo "u{262F}";
u{262F} ☯
In PHP7In PHP5
PHP 7 Removals
 Removed ASP (<%) and script (<script
language=php>) tags
 Removed support for assigning the result of new by
reference
 Removed support for #-style comments in ini files
 $HTTP_RAW_POST_DATA is no longer available. Use
the php://input stream instead.
 bye bye call_user_method()/call_user_method_array()
$a = &new stdclass;
Parse error: syntax error, unexpected 'new' (T_NEW)
PHP 7 Removals
 Removed support for scoped calls to non-static
methods from an incompatible $this context
 In PHP7, $this will be undefined in this case
class A {
function foo() { var_dump(get_class($this)); }
}
class B {
function bar() { A::foo(); }
}
$b = new B;
$b->bar();
PHP 7 Removals
class A {
function foo() { var_dump($this); }
}
class B {
function bar() { A::foo(); }
}
$b = new B;
$b->bar();
Deprecated: Non-static method A::foo() should not be
called statically, assuming $this from incompatible context
object(B) #1
Deprecated: Non-static method A::foo() should not be
called statically
Notice: Undefined variable: this in /tmp/7.php on line 4
In PHP5
In PHP7
PHP 7 Removals
 Other removals into extensions :
 Date
 Curl
 DBA
 GMP
 Mcrypt
 OpenSSL
 PCRE
 Standard
 JSON
 Many old SAPI removed (Apache1, roxen, tux, isapi ...)
PHP 7 changed behaviors
PHP 7 changed behaviors
 Redefinition of function argument is no longer allowed
function foo($a, $b, $b) { }
Fatal error: Redefinition of parameter $b in ...
PHP 7 changed behaviors
 PHP4 constructor types now generate
E_DEPRECATED, and will be removed in a next PHP
 "Types" have been turned to reserved words against
class/trait/interface names
class Foo
{
public function foo() { }
}
/* E_DEPRECATED */
class String { }
Fatal error: "string" cannot be used as a class name
PHP 7 changed behaviors
 Some reserved keywords in class context however, can
now be used
 Into a class context, expect the parser to be smoother
now :
 But you still cannot declare a const named 'class'
Project::new('Foo')->private()->for('bar');
class baz
{
private function private() { }
public function const() { }
public function list() { }
const function = 'bar';
}
PHP 7 changed behaviors
 func_get_arg() / func_get_args() now return the current
scoped variable value
function foo($x)
{
$x++;
var_dump(func_get_arg(0));
}
foo(1);
(int)1 (int)2
In PHP7In PHP5
PHP 7 changed behaviors
 Exception traces now show the current scoped
variable values
function foo($x)
{
$x++;
throw new Exception;
}
foo(1);
Stack trace:
#0 /tmp/php.php(7): foo(1)
#1 {main}
Stack trace:
#0 /tmp/php.php(7): foo(2)
#1 {main}
In PHP7In PHP5
PHP 7 changed behaviors
 Left bitwise shifts by a number of bits beyond the bit
width of an integer will always result in 0
 Bitwise shifts by negative numbers will now throw a
warning and return false
var_dump(1 << 64);
(int)1 (int)0
In PHP7In PHP5
var_dump(1 >> -1);
(int)0 (bool)false
Uncaught ArithmeticError
In PHP7In PHP5
PHP 7 changed behaviors
 Iteration with foreach() no longer has any effect on the
internal array pointer
$array = [0, 1, 2];
foreach ($array as $val) {
var_dump(current($array));
}
int(1)
int(1)
int(1)
int(0)
int(0)
int(0)
In PHP7In PHP5
PHP 7 changed behaviors
 When iterating arrays by-reference with foreach(),
modifications to the array will continue to influence
the iteration. Correct position pointer is maintained
$array = [0];
foreach ($array as &$val) {
var_dump($val);
$array[1] = 1;
}
int(0) int(0)
int(1)
In PHP7In PHP5
PHP7 : Other changes
 More generally , what before used to generate
E_DEPRECATED is now removed, or may be very soon
PHP 7 new engine
PHP 7 new internals
 Full 64bit support
 New Thread Safety mechanism
 New engine memory management
 New optimized executor
 New optimized structures
PHP 7 full 64bit engine
 PHP was known to be platform dependent on this crucial
criteria
 LP64: Linux64 (and most Unixes)
 LLP64: Windows64
 ILP64: SPARC64
http://www.unix.org/whitepapers/64bit.html
string size signed integer
Platform int long
LP64 32 64
LLP64 32 32
ILP64 64 64
PHP 7 full 64bit engine
 PHP 7 now uses platform independant sizes
 Strings > 2^31
 Real 64bit userland PHP integers
 LFS (Large File Support)
 64bits hash keys
 Whatever your platform (OS) : consistency
PHP 7 new memory management
 PHP7 has reworked every memory management
routine
 Use less heap and more stack
 Zvals are stack allocated
 refcount management more accurate
 Scalar types are no longer refcounted
 Redevelop a new MM heap, more optimized
 Based on sized pools (small, medium and large)
 CPU cache friendly
 Concepts borrowed from tcmalloc
PHP 7 thread safety
 PHP7 has reworked its thread safety mechanism
routine
 PHP5 thread safety routine had a ~20% perf impact
 This is no more the case in PHP7
 TLS is now mature, and it is used
 For PHP under Windows (mandatory)
 For PHP under Unix, if asked for (usually not)
PHP 7 new structures
 Critical structures have been reworked
 More memory friendly
 More CPU friendly (data alignment, cache friendly)
 Strings are now refcounted
 Objects now share their refcount with other types
 Wasn't the case in PHP5
 The engine Executor uses a full new stack frame to
push and manage arguments
 Function calls have been heavilly reworked
PHP 7 performances
PHP 7 performances
 A lot of tweaks have been performed against PHP 7
code performances.
 A lot of internal changes - invisible to userland - have
been performed to have a more performant language
 CPU cache misses have been heavilly worked on
 Spacial locality of code is improved
 This results in a language beeing at least twice fast
and that consumes at least twice less memory
PHP 7 performances
... ...
$x = TEST 0.664 0.269
$x = $_GET 0.876 0.480
$x = $GLOBALS['v'] 1.228 0.833
$x = $hash['v'] 1.048 0.652
$x = $str[0] 1.711 1.315
$x = $a ?: null 0.880 0.484
$x = $f ?: tmp 1.367 0.972
$x = $f ? $f : $a 0.905 0.509
$x = $f ? $f : tmp 1.371 0.976
----------------------------------------------
Total 35.412
... ...
$x = TEST 0.400 0.223
$x = $_GET 0.616 0.440
$x = $GLOBALS['v'] 0.920 0.743
$x = $hash['v'] 0.668 0.491
$x = $str[0] 1.182 1.005
$x = $a ?: null 0.529 0.352
$x = $f ?: tmp 0.614 0.438
$x = $f ? $f : $a 0.536 0.360
$x = $f ? $f : tmp 0.587 0.411
----------------------------------------------
Total 20.707
PHP7PHP5.6
Zend/micro_bench.php
PHP 7 performances
Time: 4.51 seconds, Memory: 726.00Mb
Time: 2.62 seconds, Memory: 368.00Mb
PHP7
PHP5.6
PHPUnit in Symfony2 components
Time gain ~ 40%
Memory gain ~ 50%
PHP 7 performances
 Take care of synthetic benchmarks
 They only demonstrates basic use cases
 Run your own benchmarks
 Run your own applications against PHP 7
 On a big average, you can expect dividing CPU
time and memory consumption by a factor of 2
compared to PHP-5.6, probably even more than
2
Thank you for listening !