2. 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
3. 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 ?
9. 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.
10. 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
11. 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
12. 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)
14. 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,
};
16. 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;
}
18. 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
19. 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 */
}
20. 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
21. PHP7 Exceptions instead of fatals
Some parse errors are catchable (ParseException),
especially using eval();
try {
$result = eval($code);
} catch (ParseException $exception) {
}
23. 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 */
}
24. 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) */
25. 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
26. 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
27. 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();
}
}
28. 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
29. 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) { }
30. 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
31. 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)
}
32. 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
33. 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
34. 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 */
35. 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
36. 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
37. Anonymous classes
Like anonymous functions
var_dump( new class() { });
object(class@anonymous)#1 (0) {
}
38. 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;
39. 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 ...)
42. 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
43. 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
44. 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 */
45. 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
46. 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
47. 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)
48. 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();
49. 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
50. PHP 7 Removals
Other removals into extensions :
Date
Curl
DBA
GMP
Mcrypt
OpenSSL
PCRE
Standard
JSON
Many old SAPI removed (Apache1, roxen, tux, isapi ...)
52. PHP 7 changed behaviors
Redefinition of function argument is no longer allowed
function foo($a, $b, $b) { }
Fatal error: Redefinition of parameter $b in ...
53. 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
54. 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';
}
55. 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
56. 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
57. 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
58. 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
59. 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
60. PHP7 : Other changes
More generally , what before used to generate
E_DEPRECATED is now removed, or may be very soon
62. PHP 7 new internals
Full 64bit support
New Thread Safety mechanism
New engine memory management
New optimized executor
New optimized structures
63. 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
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
65. 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
66. 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)
67. 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
69. 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
71. 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%
72. 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