$SLIDES_SOURCES = { ‘RASMUS LERDORF’, ‘ZEEV ZURASKI’, ‘JOHN MORRIS’, };
TOPIC
WILLIAM PINAUD
NINJA PROJECT MANAGER & ARCHITECT
SLIDES ♥ AFUP LIMOGES
PHP //
NEW STUFF
AND BEYOND
Q4 2018
08/06/1995 Personal Home Page 1.0 / Forms Interpreter on Usenet
01/11/1997 PHP/FI 2.0
06/06/1998 Ze + nd - PHP: Hypertext Preprocessor - PHP 3.0 - Zend Engine 1.0
22/05/2000 PHP 4.0
14/07/2004 PHP 5.0 - Zend Engine 2.0
2005 > 2010 PHP 6.0 - ICU-based engine (RIP)
03/12/2015 PHP 7.0 - Zend Engine 3.0
20XX - PHP 8.0 - Zend Engine X.X? - JIT Compiler?
RECENTLY
Yo, what’s fresh?
83.1% Websites (W3C) and growing
PHP will survive.
PHP 7.3.0 scope ✓
PHP 7.4.0 started
PHP next version discussed
7.3.0
On the one and two and three.
Non-RFC stuff.
It’s also a project.
Dead code removal (internals)
function foo(int $x, int $y) {
$a = [$x];
$a[1] = $y;
$a = $y;
return $a;
}
PHP 7.2 PHP 7.3
foo: (lines=7, args=2, vars=3, tmps=1) foo: (lines=4, args=2, vars=3,
tmps=0)
L0: CV0($x) = RECV 1 L0: CV0($x) = RECV 1
L1: CV1($y) = RECV 2 L1: CV1($y) = RECV 2
L2: CV2($a) = INIT_ARRAY 1 CV0($x) NEXT L2: CV2($a) = QM_ASSIGN
CV1($y)
L3: ASSIGN_DIM CV2($a) int(1) L3: RETURN CV2($a)
L4: OP_DATA CV1($y)
L5: ASSIGN CV2($a) CV1($y)
L6: RETURN CV2($a)
class A { }
function foo(int $x)
{
$a = new A;
$a->foo = $x;
return $x;
}
PHP 7.3
foo: (lines=2, args=1, vars=1, tmps=0)
L0: CV0($x) = RECV 1
L1: RETURN CV0($x)
Dead code removal (internals)
function foo() {
$o = new stdClass();
$o->foo = 0;
$i = 1;
$c = $i < 2;
if ($c) {
$k = 2 * $i;
$o->foo = $i;
echo $o->foo;
}
$o->foo += 2;
$o->foo++;
return $o->foo;
}
PHP 7.3
foo: (lines=2, args=0, vars=0, tmps=0)
L0: ECHO int(1)
L1: RETURN int(4)
Indenting HEREDOC/NOWDOC
$replacement = ‘vraiment’;
// PHP 5.3+, LIMITE peut être entouré de “ ”
$heredocVar = [‘truc’, <<<LIMITE
Tiens, et si on mettait du
Lorem Ipsum, juste histoire
de se marrer un peu, parce
que $replacement c’est un truc
qu’on n’a jamais vu.
LIMITE, ‘autre truc’];
$replacement = ‘vraiment’;
// PHP 5.3+, LIMITE peut être entouré de “ ”
$heredocVar = [‘truc’, <<<LIMITE
Tiens, et si on mettait du
Lorem Ipsum, juste histoire
de se marrer un peu, parce
que $replacement c’est un truc
qu’on n’a jamais vu.
LIMITE, ‘autre truc’];
/*
Array (
[0] => “truc”,
[1] => “Tiens, et si on mettait du Lorem Ipsum, juste histoire de se marrer un peu, parce
que vraiment c’est un truc qu’on n’a jamais vu.”,
[2] => “autre truc”
)
*/
PHP 7.3 +< PHP 7.3
array_key_first()
array_key_last()
Trailing commas (,) in function calls
function foo(int $x, int $y) {
//...
}
echo foo($a, $b,);
JSON parsing error thrown
JSON_THROW_ON_ERROR
PCRE2 migration - with JIT engine
list() reference assignment
$tab = [‘Hello’, ‘AFUP’];
list($a, &$b) = $tab;
$b = ‘Limoges’;
var_dump($tab[1]); string(7) "Limoges"
is_countable()
compact() fixed
Case insensitive constants deprecation
define(‘AFUP’, ‘Limoges’, true);
// Deprecated: define(): Declaration of case-insensitive constants is deprecated
Same site cookies on the way.
7.4.0
Deeper down the rabbit hole.
Strong typing in class variables /
typed properties
class Example {
public int $scalarType;
protected ClassName $classType;
private ?ClassName $nullableClassType;
public static iterable $staticProp;
var bool $flag;
public string $str = "foo";
public ?string $nullableStr = null;
public float $x, $y;
// public float $x;
// public float $y;
}
Real-life benchmarks (master vs patch)
======================================
Master typed diff
blog 169 168 -0.77%
fw 818 809 -1.10%
qdig 716 716 +0.04%
scrum 517 502 -2.84%
ZF1 Hello 2,637 2,605 -1.23%
ZF2 Test 675 667 -1.13%
wordpress-3.6 373 368 -1.47%
drupal-7.27 560 539 -3.77%
SugarCRM 470 453 -3.68%
magento-home 90 90 +0.45%
magento-cat 30 30 -0.67%
drupal-8.0.0 860 867 +0.81%
mediawiki 114 107 -6.39%
wordpress-4.1 346 344 -0.69%
symfony_demo 661 660 -0.24%
Synthetic benchmarks (master vs patch vs patch + type hints)
===========================================================
Master typed typed+hints
empty_loop 0.026 0.026 0.026
$x = self::$x 0.090 0.118 0.117
self::$x = $n 0.086 0.094 0.108
isset(self::$x) 0.075 0.091 0.092
empty(self::$x) 0.072 0.095 0.095
$x = Foo::$x 0.069 0.081 0.079
Foo::$x = $n 0.068 0.054 0.071
isset(Foo::$x) 0.053 0.051 0.051
$x = $this->x 0.128 0.126 0.105
$this->x = $n 0.057 0.059 0.065
$this->x += 2 0.096 0.098 0.120
++$this->x 0.074 0.081 0.082
--$this->x 0.075 0.082 0.082
$this->x++ 0.075 0.083 0.082
$this->x-- 0.074 0.082 0.084
isset($this->x) 0.078 0.076 0.076
empty($this->x) 0.083 0.083 0.082
$ref = $n 0.056 0.054 0.093
Performance
Impacts?
Hash functions loaded by default
7.5.0
Why and why not.
WANT SOME MORE?
8.0.0
Enter the infinite.
AoT >> JIT?
Compilation masterminds.
FFI
Breaking the walls.
<?php
$libc = new FFI("
int printf(const char *format, ...);
const char * getenv(const char *);
unsigned int time(unsigned int *);
typedef unsigned int time_t;
typedef unsigned int suseconds_t;
struct timeval {
time_t tv_sec;
suseconds_t tv_usec;
};
struct timezone {
int tz_minuteswest;
int tz_dsttime;
};
int gettimeofday(struct timeval *tv, struct timezone *tz);
", "libc.so.6");
$libc->printf("Hello AFUP from %s!n", "Limoges");
var_dump($libc->getenv("PATH"));
var_dump($libc->time(null));
$tv = $libc->new("struct timeval");
$tz = $libc->new("struct timezone");
$libc->gettimeofday(FFI::addr($tv), FFI::addr($tz));
var_dump($tv->tv_sec, $tv->tv_usec, $tz);
?>
Hello AFUP from Limoges!
string(135) "/usr/lib64/qt-
3.3/bin:/usr/lib64/ccache:/usr/local/bin:/usr/
bin:/bin:/usr/loc"
int(1523617815)
int(1523617815)
int(977765)
object(FFICData:<struct>)#3 (2) {
["tz_minuteswest"]=>
int(-180)
["tz_dsttime"]=>
int(0)
}
<?php
$p = FFI::new("int[2]");
$p[0] = 1;
$p[1] = 2;
foreach ($p as $key => $val) {
echo "$key => $valn";
}
// “0 => 1n”
// “1 => 2n”
$pp = FFI::new("struct {int x,y;}[2]");
foreach($pp as $n => &$p) {
$p->x = $p->y = $n;
}
var_dump($pp);
object(FFICData:<struct>[2])#1 (2) {
[0]=>
object(FFICData:<struct>)#2 (2) {
["x"]=>
int(0)
["y"]=>
int(0)
}
[1]=>
object(FFICData:<struct>)#3 (2) {
["x"]=>
int(1)
["y"]=>
int(1)
}
}
?>
OpCache core
I’ve already seen that cat.
PreLoading
Did you see that coming?
Asynchronism
Legen… Wait for it. Dary. Legendary.
Merging symbols tables
Already defined, mate.
Extend instanceof
You’re my type.
Negative Index
array_keys(array_fill(-2, 4, true)); // [-2, 0, 1, 2]; - PHP 7.2.9
array_keys(array_fill(-2, 4, true)); // [-2, -1, 0, 1]; - PHP 8.0.0
Null coalesce equals?
$a = null;
$b = “test”;
$a ??= ‘yep’; // $a === ‘yep’
$b ??= ‘yep’; // $b === ‘test’
Case insensitive
constants removed
UNLESS you CARE about THAT, It’S QuIte CoOL.
Many other deletions.
Consistency fixes.
“But for those of us who’d lived and died in them furious days,
it was like everything we knew was mightily swept away.”
THANK YOU ❤
WILLIAM PINAUD
NINJA PROJECT MANAGER & ARCHITECT
SLIDES ♥ AFUP LIMOGES

PHP in 2018 - Q4 - AFUP Limoges

  • 2.
    $SLIDES_SOURCES = {‘RASMUS LERDORF’, ‘ZEEV ZURASKI’, ‘JOHN MORRIS’, }; TOPIC
  • 3.
    WILLIAM PINAUD NINJA PROJECTMANAGER & ARCHITECT SLIDES ♥ AFUP LIMOGES PHP // NEW STUFF AND BEYOND Q4 2018
  • 4.
    08/06/1995 Personal HomePage 1.0 / Forms Interpreter on Usenet 01/11/1997 PHP/FI 2.0 06/06/1998 Ze + nd - PHP: Hypertext Preprocessor - PHP 3.0 - Zend Engine 1.0 22/05/2000 PHP 4.0 14/07/2004 PHP 5.0 - Zend Engine 2.0 2005 > 2010 PHP 6.0 - ICU-based engine (RIP) 03/12/2015 PHP 7.0 - Zend Engine 3.0 20XX - PHP 8.0 - Zend Engine X.X? - JIT Compiler?
  • 5.
  • 6.
  • 7.
  • 8.
    PHP 7.3.0 scope✓ PHP 7.4.0 started PHP next version discussed
  • 9.
    7.3.0 On the oneand two and three.
  • 10.
  • 11.
    Dead code removal(internals) function foo(int $x, int $y) { $a = [$x]; $a[1] = $y; $a = $y; return $a; } PHP 7.2 PHP 7.3 foo: (lines=7, args=2, vars=3, tmps=1) foo: (lines=4, args=2, vars=3, tmps=0) L0: CV0($x) = RECV 1 L0: CV0($x) = RECV 1 L1: CV1($y) = RECV 2 L1: CV1($y) = RECV 2 L2: CV2($a) = INIT_ARRAY 1 CV0($x) NEXT L2: CV2($a) = QM_ASSIGN CV1($y) L3: ASSIGN_DIM CV2($a) int(1) L3: RETURN CV2($a) L4: OP_DATA CV1($y) L5: ASSIGN CV2($a) CV1($y) L6: RETURN CV2($a) class A { } function foo(int $x) { $a = new A; $a->foo = $x; return $x; } PHP 7.3 foo: (lines=2, args=1, vars=1, tmps=0) L0: CV0($x) = RECV 1 L1: RETURN CV0($x)
  • 12.
    Dead code removal(internals) function foo() { $o = new stdClass(); $o->foo = 0; $i = 1; $c = $i < 2; if ($c) { $k = 2 * $i; $o->foo = $i; echo $o->foo; } $o->foo += 2; $o->foo++; return $o->foo; } PHP 7.3 foo: (lines=2, args=0, vars=0, tmps=0) L0: ECHO int(1) L1: RETURN int(4)
  • 13.
  • 14.
    $replacement = ‘vraiment’; //PHP 5.3+, LIMITE peut être entouré de “ ” $heredocVar = [‘truc’, <<<LIMITE Tiens, et si on mettait du Lorem Ipsum, juste histoire de se marrer un peu, parce que $replacement c’est un truc qu’on n’a jamais vu. LIMITE, ‘autre truc’]; $replacement = ‘vraiment’; // PHP 5.3+, LIMITE peut être entouré de “ ” $heredocVar = [‘truc’, <<<LIMITE Tiens, et si on mettait du Lorem Ipsum, juste histoire de se marrer un peu, parce que $replacement c’est un truc qu’on n’a jamais vu. LIMITE, ‘autre truc’]; /* Array ( [0] => “truc”, [1] => “Tiens, et si on mettait du Lorem Ipsum, juste histoire de se marrer un peu, parce que vraiment c’est un truc qu’on n’a jamais vu.”, [2] => “autre truc” ) */ PHP 7.3 +< PHP 7.3
  • 15.
  • 16.
    Trailing commas (,)in function calls function foo(int $x, int $y) { //... } echo foo($a, $b,);
  • 17.
    JSON parsing errorthrown JSON_THROW_ON_ERROR
  • 18.
    PCRE2 migration -with JIT engine
  • 19.
  • 20.
    $tab = [‘Hello’,‘AFUP’]; list($a, &$b) = $tab; $b = ‘Limoges’; var_dump($tab[1]); string(7) "Limoges"
  • 21.
  • 22.
  • 23.
    Case insensitive constantsdeprecation define(‘AFUP’, ‘Limoges’, true); // Deprecated: define(): Declaration of case-insensitive constants is deprecated
  • 24.
    Same site cookieson the way.
  • 25.
  • 26.
    Strong typing inclass variables / typed properties
  • 27.
    class Example { publicint $scalarType; protected ClassName $classType; private ?ClassName $nullableClassType; public static iterable $staticProp; var bool $flag; public string $str = "foo"; public ?string $nullableStr = null; public float $x, $y; // public float $x; // public float $y; }
  • 28.
    Real-life benchmarks (mastervs patch) ====================================== Master typed diff blog 169 168 -0.77% fw 818 809 -1.10% qdig 716 716 +0.04% scrum 517 502 -2.84% ZF1 Hello 2,637 2,605 -1.23% ZF2 Test 675 667 -1.13% wordpress-3.6 373 368 -1.47% drupal-7.27 560 539 -3.77% SugarCRM 470 453 -3.68% magento-home 90 90 +0.45% magento-cat 30 30 -0.67% drupal-8.0.0 860 867 +0.81% mediawiki 114 107 -6.39% wordpress-4.1 346 344 -0.69% symfony_demo 661 660 -0.24% Synthetic benchmarks (master vs patch vs patch + type hints) =========================================================== Master typed typed+hints empty_loop 0.026 0.026 0.026 $x = self::$x 0.090 0.118 0.117 self::$x = $n 0.086 0.094 0.108 isset(self::$x) 0.075 0.091 0.092 empty(self::$x) 0.072 0.095 0.095 $x = Foo::$x 0.069 0.081 0.079 Foo::$x = $n 0.068 0.054 0.071 isset(Foo::$x) 0.053 0.051 0.051 $x = $this->x 0.128 0.126 0.105 $this->x = $n 0.057 0.059 0.065 $this->x += 2 0.096 0.098 0.120 ++$this->x 0.074 0.081 0.082 --$this->x 0.075 0.082 0.082 $this->x++ 0.075 0.083 0.082 $this->x-- 0.074 0.082 0.084 isset($this->x) 0.078 0.076 0.076 empty($this->x) 0.083 0.083 0.082 $ref = $n 0.056 0.054 0.093 Performance Impacts?
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 35.
  • 36.
    <?php $libc = newFFI(" int printf(const char *format, ...); const char * getenv(const char *); unsigned int time(unsigned int *); typedef unsigned int time_t; typedef unsigned int suseconds_t; struct timeval { time_t tv_sec; suseconds_t tv_usec; }; struct timezone { int tz_minuteswest; int tz_dsttime; }; int gettimeofday(struct timeval *tv, struct timezone *tz); ", "libc.so.6"); $libc->printf("Hello AFUP from %s!n", "Limoges"); var_dump($libc->getenv("PATH")); var_dump($libc->time(null)); $tv = $libc->new("struct timeval"); $tz = $libc->new("struct timezone"); $libc->gettimeofday(FFI::addr($tv), FFI::addr($tz)); var_dump($tv->tv_sec, $tv->tv_usec, $tz); ?> Hello AFUP from Limoges! string(135) "/usr/lib64/qt- 3.3/bin:/usr/lib64/ccache:/usr/local/bin:/usr/ bin:/bin:/usr/loc" int(1523617815) int(1523617815) int(977765) object(FFICData:<struct>)#3 (2) { ["tz_minuteswest"]=> int(-180) ["tz_dsttime"]=> int(0) }
  • 37.
    <?php $p = FFI::new("int[2]"); $p[0]= 1; $p[1] = 2; foreach ($p as $key => $val) { echo "$key => $valn"; } // “0 => 1n” // “1 => 2n” $pp = FFI::new("struct {int x,y;}[2]"); foreach($pp as $n => &$p) { $p->x = $p->y = $n; } var_dump($pp); object(FFICData:<struct>[2])#1 (2) { [0]=> object(FFICData:<struct>)#2 (2) { ["x"]=> int(0) ["y"]=> int(0) } [1]=> object(FFICData:<struct>)#3 (2) { ["x"]=> int(1) ["y"]=> int(1) } } ?>
  • 38.
  • 39.
  • 40.
    Asynchronism Legen… Wait forit. Dary. Legendary.
  • 41.
  • 42.
  • 43.
    Negative Index array_keys(array_fill(-2, 4,true)); // [-2, 0, 1, 2]; - PHP 7.2.9 array_keys(array_fill(-2, 4, true)); // [-2, -1, 0, 1]; - PHP 8.0.0
  • 44.
    Null coalesce equals? $a= null; $b = “test”; $a ??= ‘yep’; // $a === ‘yep’ $b ??= ‘yep’; // $b === ‘test’
  • 45.
    Case insensitive constants removed UNLESSyou CARE about THAT, It’S QuIte CoOL.
  • 46.
    Many other deletions. Consistencyfixes. “But for those of us who’d lived and died in them furious days, it was like everything we knew was mightily swept away.”
  • 47.
    THANK YOU ❤ WILLIAMPINAUD NINJA PROJECT MANAGER & ARCHITECT SLIDES ♥ AFUP LIMOGES