Share
Embed
[PHPConf.Asia 2016] Keynote: PHP Is Dead
In this keynote for PHPConf.Asia we explore the possibility that PHP is a dying language, and how we as a community can change that.
Davey Shafik
August 23, 2016
Transcript
265 slides
-
P H P CO N F. A S I A
K E Y N OT E CC-BY-ND 2.0: Michaela Loheit -
h tt p : / /d e v e l
o p e r. a ka m a i .co m -
R E L E A S E M A N
A G E R -
P H P I S D E A D CC-BY
2.0: Nana B Agyei -
S I N G L E - PAG E A
P P L I C AT I O N S A R E T H E F U T U R E -
S I N G L E PA G E A
P P L I C AT I O N S A R E T H E F U T U R E 2011 2016 Source: Google Trends -
S I N G L E PA G E A
P P L I C AT I O N S A R E T H E F U T U R E 2011 2016 Source: Google Trends -
C L I E N T S I D E
M VC F R A M E W O R K S A R E T H E F U T U R E -
C L I E N T S I D E
M V C F R A M E W O R K S A R E T H E F U T U R E 2010 2016 angular react Source: Google Trends -
C L I E N T S I D E
M V C F R A M E W O R K S A R E T H E F U T U R E 2010 2016 angular react Source: Google Trends -
J AVA S C R I PT I S T
H E F U T U R E -
J AVA S C R I PT I S W
I N N I N G 2004 2016 -
P H P I S J AVA S C R
I PT Source: Google Trends 2016 2004 -
N E W L A N G UAG E S
A R E W I N N I N G -
R UST I S W I N N I N
G 2012 2016 Source: Google Trends -
R UST I S W I N N I N
G 2012 2016 Source: Google Trends -
G O L A N G I S W I
N N I N G Source: Google Trends 2010 2016 -
G O L A N G I S W I
N N I N G 2010 2016 Source: Google Trends -
G O L A N G V S R UST
2010 2016 Golang Rust Source: Google Trends -
G O L A N G V S R UST
V S P H P 2010 2016 Rust Golang PHP Source: Google Trends -
M AY B E I T ’ S T H
E PA R A D I G M ? -
O BJ E CT O R I E N T
E D V S F U N CT I O N A L P R O G R A M M I N G 2004 2016 Object-Oriented Functional Source: Google Trends -
O BJ E CT O R I E N T
E D V S F U N CT I O N A L P R O G R A M M I N G 2004 2016 Object-Oriented Functional Source: Google Trends -
M AY B E I T ’ S T H
E S K I L LS E T ! -
F U L L STA C K D E V
E LO P E R V S 1 0 X E N G I N E E R 2010 2016 Full Stack Developer 10X Engineer Source: Google Trends -
F U L L STA C K D E V
E LO P E R V S 1 0 X E N G I N E E R 2010 2016 Full Stack Developer 10X Engineer Source: Google Trends -
F U L L STA C K D E V
E LO P E R V S 1 0 X E N G I N E E R 2016 10X engineer Full Stack Developer PHP Developer Source: Google Trends -
R I P H P ? CC-BY 2.0: johnny myreng
henriksen -
W H AT D O E S P R O
G R E SS LO O K L I K E ? CC-BY 2.0: damon jah -
P H P U S A G E PHP ASP.NET
Java Static Files Coldfusion Ruby Other 1% 0.6% 0.7% 1.5% 2.7% 15.8% 82.1% Source: w3techs -
P H P R E L E A S E
S 2 3 4 5 6 7 8 9 2012-02 2012-05 2012-08 2012-11 2013-02 2013-05 2013-08 2013-11 2014-02 2014-05 2014-08 2014-11 2015-02 2015-05 2015-08 2015-11 2016-02 2016-05 Source: php-src git repository -
P H P V E RS I O N US
A G E PHP 7.x PHP 5.x PHP 4.x 1.1% 97.8% 1.2% Source: w3techs -
CO N T E XT: 1 2 M O N
T H S -
P H P 5 : T H E F I
RST 1 2 M O N T H S PHP 5.0 Release Source: Google Trends -
P H P 7 : T H E F I
RST 1 2 M O N T H S PHP 7.0 Release Source: Google Trends -
P H P 7 : T H E F I
RST 1 2 M O N T H S PHP 7 PHP 5 Source: Google Trends PHP 5.0/7.0 Release -
T H I R D - PA RTY E CO
SYST E M -
PAC K AG I ST: PA C KA G E
S & R E L E A S E S 0K 150K 300K 450K 600K 2011-09 2011-12 2012-03 2012-06 2012-09 2012-12 2013-03 2013-06 2013-09 2013-12 2014-03 2014-06 2014-09 2014-12 2015-03 2015-06 2015-09 2015-12 2016-03 2016-06 568K 105K Packages Versions Source: Packagist -
PAC K AG I ST: PA C KA G E
I N STA L LS ( AV E R AG E / D AY ) 0M 45M 90M 135M 180M 2012-04 2012-07 2012-10 2013-01 2013-04 2013-07 2013-10 2014-01 2014-04 2014-07 2014-10 2015-01 2015-04 2015-07 2015-10 2016-01 2016-04 169M Source: Packagist -
P H P : A F R A C TA
L O F B A D D E S I G N CC-BY 2.0: Ian Baker A P R I L 9 T H 2 0 1 2 -
P R E D I CTA B L E &
CO N S I ST E N T CC-BY-SA: InSapphoWeTrust -
L AT E STAT I C B I N D
I N G -
U N I F O R M VA R I
A B L E SY N TA X -
L A N G UA G E S P E
C I F I C AT I O N -
A N O N Y M O US C L
A SS E S -
R E L I A B L E CC-BY 2.0:
mpclemens -
S H A R E D - N OT H
I N G A R C H I T E CT U R E -
D E B U G G A B L E
CC-BY-SA 2.0: Peter Grima -
P H P I S N OT E VO LV
I N G CC-BY 2.0: Duncan Hull -
S H O RT E C H O TAG S
P H P 5 . 4 -
B I N A R Y N U M B
E RS P H P 5 . 4 -
S H O RT A R R AY SY N
TA X P H P 5 . 4 -
A R R AY D E R E F E
R E N C I N G P H P 5 . 4 -
C LO S U R E $ T H I
S B I N D I N G P H P 5 . 4 -
C A L L A B L E TY P
E H I N T P H P 5 . 4 -
B U I LT I N C L I S
E R V E R P H P 5 . 4 -
L I ST S U P P O RT I
N FO R E A C H P H P 5 . 5 -
A R B I T R A R Y E
X P R E SS I O N S U P P O RT F O R E M P T Y ( ) P H P 5 . 5 -
ST R I N G /A R R AY D
E R E F E R E N C I N G P H P 5 . 5 -
F I N A L LY B LO C K
S P H P 5 . 5 -
E XT/ PA SS W O R D P H
P 5 . 5 -
G E N E R ATO RS P H P
5 . 5 -
L A N G UA G E S P E
C I F I C AT I O N T H A N K S FAC E B O O K ! -
E X P O N E N T O P
E R ATO R ( T _ P O W ) P H P 5 . 6 -
CO N STA N T S C A L A
R E X P R E SS I O N S P H P 5 . 6 -
I M P O RT F U N CT I
O N S / CO N STA N TS P H P 5 . 6 -
VA R I A D I CS P H P
5 . 6 -
A R G U M E N T U N
PAC K I N G ( S P L AT ) P H P 5 . 6 -
R E M O V E A LT E R
N AT I V E P H P TA G S P H P 7 . 0 -
R E M O V E P O S I
X R E G E X P H P 7 . 0 -
R E M O V E E XT/ M YS
Q L P H P 7 . 0 -
2 . 4 X FA ST E R P H
P 7 . 0 -
A BST R ACT SY N TA X T R
E E P H P 7 . 0 -
U N I F O R M VA R I
A B L E SY N TA X P H P 7 . 0 -
E N G I N E E XC E PT
I O N S P H P 7 . 0 -
U N I CO D E E S C A
P E SY N TA X P H P 7 . 0 -
N U L L COA L E S C E
O P E R ATO R P H P 7 . 0 -
B I N D C LO S U R E
O N C A L L P H P 7 . 0 -
G R O U P US E D E C
L A R AT I O N S P H P 7 . 0 -
G E N E R ATO R D E L
E G AT I O N P H P 7 . 0 -
G E N E R ATO R R E T
U R N VA LU E S P H P 7 . 0 -
A N O N Y M O US C L
A SS E S P H P 7 . 0 -
S C A L A R TY P E H
I N TS P H P 7 . 0 -
R E T U R N H I N TS
P H P 7 . 0 -
ST R I CT TY P E S P H
P 7 . 0 -
S PA C E S H I P O P
E R ATO R P H P 7 . 0 -
CO M B I N E D CO M PA
R I S O N O P E R ATO R P H P 7 . 0 -
T H E F U T U R E Credit:
NASA/KSC -
TO O F E W A R G U M
E N TS E XC E PT I O N -
TO O F E W A R G U M
E N TS E XC E PT I O N • Throw an exception when too few arguments are passed to a user defined function/method regardless of strict types • Backwards compatibility break -
TO O F E W A R G U M
E N TS E XC E PT I O N function hello($whom) { echo "Hello $whom"; } hello(); 1 2 3 4 5 6 -
TO O F E W A R G U M
E N TS E XC E PT I O N function hello($whom) { echo "Hello $whom"; } hello(); 1 2 3 4 5 6 -
function hello($whom) { echo "Hello $whom"; } hello(); TO O
F E W A R G U M E N TS E XC E PT I O N 1 2 3 4 5 6 -
function hello($whom) { echo "Hello $whom"; } hello(); TO O
F E W A R G U M E N TS E XC E PT I O N 1 2 3 4 5 6 -
function hello($whom) { echo "Hello $whom"; } hello(); TO O
F E W A R G U M E N TS E XC E PT I O N 1 2 3 4 5 6 -
function hello($whom) { echo "Hello $whom"; } hello(); TO O
F E W A R G U M E N TS E XC E PT I O N 1 2 3 4 5 6 Warning: Missing argument 1 for hello(), called in <file> on line 6 and defined in <file> on line 1 -
function hello($whom) { echo "Hello $whom"; } hello(); TO O
F E W A R G U M E N TS E XC E PT I O N 1 2 3 4 5 6 Notice: Undefined variable: what in <file> on line 4 Hello -
TO O F E W A R G U M
E N TS E XC E PT I O N 1 2 3 4 5 6 function hello($whom) { echo "Hello $whom"; } hello(); -
function hello($whom) { echo "Hello $whom"; } hello(); TO O
F E W A R G U M E N TS E XC E PT I O N 1 2 3 4 5 6 Fatal error: Uncaught Error: Too few arguments to function hello(), 0 passed in <file> on line 6 and exactly 1 expected in <file>:2 -
TO O F E W A R G U M
E N TS E XC E PT I O N function hello($whom) { echo "Hello $whom"; } try { hello(); } catch (\Error $e) { // Handle exception } 1 2 3 4 5 6 7 8 9 10 -
TO O F E W A R G U M
E N TS E XC E PT I O N function hello($whom) { echo "Hello $whom"; } try { hello(); } catch (\Error $e) { // Handle exception } 1 2 3 4 5 6 7 8 9 10 -
function hello($whom) { echo "Hello $whom"; } try { hello();
} catch (\Error $e) { // Handle exception } TO O F E W A R G U M E N TS E XC E PT I O N 1 2 3 4 5 6 7 8 9 10 -
function hello($whom) { echo "Hello $whom"; } try { hello();
} catch (\Error $e) { // Handle exception } TO O F E W A R G U M E N TS E XC E PT I O N 1 2 3 4 5 6 7 8 9 10 -
function hello($whom, $when) { echo "Hello $whom, have a good
$when"; } try { $args = ['World']; hello(... $args); } catch (\Error $e) { // Handle exception } TO O F E W A R G U M E N TS E XC E PT I O N 1 2 3 4 5 6 7 8 9 10 11 -
function hello($whom, $when) { echo "Hello $whom, have a good
$when"; } try { $args = ['World']; hello(... $args); } catch (\Error $e) { // Handle exception } TO O F E W A R G U M E N TS E XC E PT I O N 1 2 3 4 5 6 7 8 9 10 11 -
function hello($whom, $when) { echo "Hello $whom, have a good
$when"; } try { $args = ['World']; hello(... $args); } catch (\Error $e) { // Handle exception } TO O F E W A R G U M E N TS E XC E PT I O N 1 2 3 4 5 6 7 8 9 10 11 -
N E G AT I V E ST R I
N G O F FS E TS -
N E G AT I V E ST R I
N G O F FS E TS • Consistently support negative string offsets • Similar to substr() • In string character accessors • Internal functions -
N E G AT I V E ST R I
N G O F FS E TS $path = "/path/to/somewhere/"; if (substr($path, -1) !== '/') { $path = substr($path, 0, -1); } -
N E G AT I V E ST R I
N G O F FS E TS $path = "/path/to/somewhere/"; if (substr($path, -1) !== '/') { $path = substr($path, 0, -1); } -
N E G AT I V E ST R I
N G O F FS E TS $path = "/path/to/somewhere/"; if ($path[-1] === '/') { $path = substr($path, 0, -1); } -
N E G AT I V E ST R I
N G O F FS E TS $path = "/path/to/somewhere/"; if ($path{-1} === '/') { $path = substr($path, 0, -1); } -
S E T C H A R A CT E
RS $string = "abc"; $string[-2] = "z"; // $string == "azc" -
C H E C K L E N GT H
if (strlen($_POST['password']) < 8) { // Do something } if (!isset($_POST['password'][7])) { // Do something } if (!isset($_POST['password'][-8])) { // Do something } -
if (strlen($_POST['password']) < 8) { // Do something } if
(!isset($_POST['password'][7])) { // Do something } if (!isset($_POST['password'][-8])) { // Do something } C H E C K L E N GT H -
if (strlen($_POST['password']) < 8) { // Do something } if
(!isset($_POST['password'][7])) { // Do something } if (!isset($_POST['password'][-8])) { // Do something } C H E C K L E N GT H -
F U N CT I O N S U P
P O RT strpos() stripos() substr_count() grapheme_strpos() grapheme_stripos() grapheme_extract() iconv_strpos() file_get_contents() mb_strimwidth() mb_ereg_search_setpos() mb_strpos() mb_stripos() -
C LO S U R E F R O M
C A L L A B L E -
C LO S U R E F R O M
C A L L A B L E class Closure { public static function fromCallable(callable $callable): Closure { ... } } -
C LO S I N G OV E R S
CO P E -
C LO S I N G O V E R
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData); -
C LO S I N G O V E R
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData); -
C LO S I N G O V E R
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData); -
C LO S I N G O V E R
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData); -
C LO S I N G O V E R
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData); -
C LO S I N G O V E R
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData); -
C LO S I N G O V E R
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData); -
C LO S I N G O V E R
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData); -
C LO S I N G O V E R
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData); -
C LO S I N G O V E R
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData); -
C LO S I N G O V E R
S CO P E Fatal error: Uncaught Error: Call to private method Validator::emailValidation() from context '' in <file>:<line> -
C LO S I N G O V E R
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData); -
C LO S I N G O V E R
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData); -
C LO S I N G O V E R
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } public function emailValidation($userData) {...} public function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData); -
C LO S I N G O V E R
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } public function emailValidation($userData) {...} public function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData); -
C LO S I N G O V E R
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData); -
C LO S I N G O V E R
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return Closure::fromCallable([$this, 'emailValidation']); } return Closure::fromCallable([$this, 'genericValidation']); } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData); -
C LO S I N G O V E R
S CO P E class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return Closure::fromCallable([$this, 'emailValidation']); } return Closure::fromCallable([$this, 'genericValidation']); } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData); -
B E T T E R E R R O
R H A N D L I N G -
B E T T E R E R R O
R H A N D L I N G class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return Closure::fromCallable([$this, 'emailValidation']); } return Closure::fromCallable([$this, 'genericValidation']); } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData); -
B E T T E R E R R O
R H A N D L I N G class Validator { public function getValidatorCallback($validationType) { if ($validationType == 'email') { return Closure::fromCallable([$this, 'emailValdation']); } return Closure::fromCallable([$this, 'genericValidation']); } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData); -
B E T T E R E R R O
R H A N D L I N G TypeError: Failed to create closure from callable: class 'Validator' does not have a method 'emailValdation' in <file>:<line> -
B E T T E R E R R O
R H A N D L I N G TypeError: Failed to create closure from callable: function 'foo' not found or invalid function name in <file>:<line> -
C L A SS CO N STA N T V
I S I B I L I TY -
C L A SS CO N STA N T V
I S I B I L I TY class MyClass { const MY_CONSTANT = 0; const MY_OTHER_CONSTANT = 1; const MY_FAVORITE_CONSTANT = 2; const FOO = 1, BAR = 2; } -
C L A SS CO N STA N T V
I S I B I L I TY class MyClass { public const MY_CONSTANT = 0; protected const MY_OTHER_CONSTANT = 1; private const MY_FAVORITE_CONSTANT = 2; private const FOO = 1, BAR = 2; } -
C L A SS CO N STA N T V
I S I B I L I TY class MyClass { public const MY_CONSTANT = 0; protected const MY_OTHER_CONSTANT = 1; private const MY_FAVORITE_CONSTANT = 2; private const FOO = 1, BAR = 2; } -
C L A SS CO N STA N T V
I S I B I L I TY class MyClass { public const MY_CONSTANT = 0; protected const MY_OTHER_CONSTANT = 1; private const MY_FAVORITE_CONSTANT = 2; private const FOO = 1, BAR = 2; } -
C L A SS CO N STA N T V
I S I B I L I TY class MyClass { public const MY_CONSTANT = 0; protected const MY_OTHER_CONSTANT = 1; private const MY_FAVORITE_CONSTANT = 2; private const FOO = 1, BAR = 2; } -
C L A SS CO N STA N T V
I S I B I L I TY class MyClass { public const MY_CONSTANT = 0; protected const MY_OTHER_CONSTANT = 1; private const MY_FAVORITE_CONSTANT = 2; private const FOO = 1, BAR = 2; } -
I N T E R FA C E CO N
STA N T V I S I B I L I TY interface MyInterface { public const MY_CONSTANT = 0; protected const MY_OTHER_CONSTANT = 1; private const MY_FAVORITE_CONSTANT = 2; private const FOO = 1, BAR = 2; } -
E N H A N C E M E N
TS TO R E F L E CT I O N • Added ReflectionClass->getReflectionConstant() • Added ReflectionClass->getReflectionConstants() • Both return ReflectionClassConstant instances -
E N H A N C E M E N
TS TO R E F L E CT I O N class ReflectionClassConstant { public function getName() { } public function getValue() { } public function isPublic() { } public function isPrivate() { } public function isProtected() { } public function getModifiers() { } public function getDeclaringClass() { } public function getDocComment() { } } -
C ATC H I N G M U LT I
P L E E XC E PT I O N S -
C ATC H I N G M U LT I
P L E E XC E PT I O N S try { ... } catch (\PDOException $e) { \My\App::renderError(500); } catch (\My\RequestException $e) { \My\App::renderError(500); } catch (\My\RequestMethodException $e) { \My\App::renderError(405); } -
C ATC H I N G M U LT I
P L E E XC E PT I O N S try { ... } catch (\PDOException $e) { \My\App::renderError(500); } catch (\My\RequestException $e) { \My\App::renderError(500); } catch (\My\RequestMethodException $e) { \My\App::renderError(405); } -
C ATC H I N G M U LT I
P L E E XC E PT I O N S try { ... } catch (\PDOException $e) { \My\App::renderError(500); } catch (\My\RequestException $e) { \My\App::renderError(500); } catch (\My\RequestMethodException $e) { \My\App::renderError(405); } -
C ATC H I N G M U LT I
P L E E XC E PT I O N S try { ... } catch (\PDOException $e) { \My\App::renderError(500); } catch (\My\RequestException $e) { \My\App::renderError(500); } catch (\My\RequestMethodException $e) { \My\App::renderError(405); } -
C ATC H I N G M U LT I
P L E E XC E PT I O N S try { ... } catch (\PDOException $e) { \My\App::renderError(500); } catch (\My\RequestException $e) { \My\App::renderError(500); } catch (\My\RequestMethodException $e) { \My\App::renderError(405); } -
C ATC H I N G M U LT I
P L E E XC E PT I O N S try { ... } catch (\PDOException $e) { \My\App::renderError(500); } catch (\My\RequestException $e) { \My\App::renderError(500); } catch (\My\RequestMethodException $e) { \My\App::renderError(405); } -
C ATC H I N G M U LT I
P L E E XC E PT I O N S try { ... } catch (\PDOException | \My\RequestException $e) { \My\App::renderError(500); } catch (\My\RequestMethodException $e) { \My\App::renderError(405); } -
C ATC H I N G M U LT I
P L E E XC E PT I O N S try { ... } catch (\PDOException | \My\RequestException $e) { \My\App::renderError(500); } catch (\My\RequestMethodException $e) { \My\App::renderError(405); } -
L I S T ( ) I M P R
OV E M E N TS -
S P E C I F Y I N G
K E YS I N L I S T ( ) -
S P E C I F Y I N G
K E YS I N L I S T ( ) $coords = [ 'lat' => '1.3521° N', 'long' => '103.8198° E' ]; list($lat, $long) = $coords; var_dump($lat, $long); -
S P E C I F Y I N G
K E YS I N L I S T ( ) $coords = [ 'lat' => '1.3521° N', 'long' => '103.8198° E' ]; list($lat, $long) = $coords; var_dump($lat, $long); -
S P E C I F Y I N G
K E YS I N L I S T ( ) $coords = [ 'lat' => '1.3521° N', 'long' => '103.8198° E' ]; list($lat, $long) = $coords; var_dump($lat, $long); -
S P E C I F Y I N G
K E YS I N L I S T ( ) $coords = [ 'lat' => '1.3521° N', 'long' => '103.8198° E' ]; list($lat, $long) = $coords; var_dump($lat, $long); Notice: Undefined offset: 0 Notice: Undefined offset: 1 -
S P E C I F Y I N G
K E YS I N L I S T ( ) $coords = [ 'lat' => '1.3521° N', 'long' => '103.8198° E' ]; list($lat, $long) = $coords; var_dump($lat, $long); -
S P E C I F Y I N G
K E YS I N L I S T ( ) $coords = [ 'lat' => '1.3521° N', 'long' => '103.8198° E' ]; list($lat, $long) = $coords; var_dump($lat, $long); $lat === NULL $long === NULL -
S P E C I F Y I N G
K E YS I N L I S T ( ) $coords = [ 'lat' => '1.3521° N', 'long' => '103.8198° E' ]; list($lat, $long) = $coords; var_dump($lat, $long); -
S P E C I F Y I N G
K E YS I N L I S T ( ) $coords = [ 'lat' => '1.3521° N', 'long' => '103.8198° E' ]; list('lat' => $lat, 'long' => $long) = $coords; var_dump($lat, $long); -
S P E C I F Y I N G
K E YS I N L I S T ( ) $coords = [ 'lat' => '1.3521° N', 'long' => '103.8198° E' ]; list('lat' => $lat, 'long' => $long) = $coords; var_dump($lat, $long); -
S P E C I F Y I N G
K E YS I N L I S T ( ) $coords = [ 'lat' => '1.3521° N', 'long' => '103.8198° E' ]; list('lat' => $lat, 'long' => $long) = $coords; var_dump($lat, $long); $lat === '1.3521° N' $long === '103.8198° E' -
S K I P P I N G N U
M E R I C K E YS -
S K I P P I N G N U
M E R I C K E YS list( , $lat, $long, , , $name ) = getLocation(); -
S K I P P I N G N U
M E R I C K E YS list( , $lat, $long, , , $name ) = getLocation(); -
S K I P P I N G N U
M E R I C K E YS list( 1 => $lat, 2 => $long, 5 => $name ) = getLocation(); -
S H O RT L I ST ( ) SY
N TA X -
S H O RT L I ST ( ) SY
N TA X list('lat' => $lat, 'long' => $long) = $coords; -
S H O RT L I ST ( ) SY
N TA X ['lat' => $lat, 'long' => $long] = $coords; -
S H O RT L I ST ( ) SY
N TA X : M U T UA L LY E XC LU S I V E SY N TA X // This is not allowed: list([$a, $b], [$c, $d]) = [[1, 2], [3, 4]]; // This is also not allowed: [list($a, $b), list($c, $d)] = [[1, 2], [3, 4]]; // This, however, is allowed: [[$a, $b], [$c, $d]] = [[1, 2], [3, 4]]; // This also: list(list($a, $b), list($c, $d)) = [[1, 2], [3, 4]]; -
I T E R A B L E PS U
E D OTY P E -
I T E R A B L E P S
U E D OTY P E • Similar to callable but values you can foreach, or yield • Accepts any array, or object that implements Traversable • SPL Iterators • Generators • Can be used for return value -
I T E R A B L E P S
U E D OTY P E function enumerate(iterable $args) { foreach ($args as $arg) { echo $args; } } -
I T E R A B L E P S
U E D OTY P E function enumerate(iterable $args) { foreach ($args as $arg) { echo $args; } } -
I T E R A B L E P S
U E D OTY P E function enumerate(iterable $args) { foreach ($args as $arg) { echo $args; } } -
I T E R A B L E P S
U E D OTY P E : R E T U R N TY P E function compactor(... $args): iterable { return $args; } -
I T E R A B L E P S
U E D OTY P E : R E T U R N TY P E function compactor(... $args): iterable { return $args; } -
I T E R A B L E P S
U E D OTY P E : R E T U R N TY P E function compactor(... $args): iterable { return $args; } -
I T E R A B L E P S
U E D OTY P E : G E N E R ATO RS function compactor(... $args): iterable { foreach ($args as $arg) { yield $arg; } } -
A D D S I S _ I T E
R A B L E ( ) F U N CT I O N // true is_iterable([1, 2, 3]); is_iterable(new ArrayIterator([1, 2, 3])); is_iterable((function () { yield 1; })()); // false is_iterable(1); is_iterable("Hello World"); is_iterable(new stdClass()); -
V O I D R E T U R N
TY P E -
V O I D R E T U R N
TY P E • PHP functions implicitly return null • There is a semantic difference between returning null, and returning nothing (or not returning) • Void enforces this behavior • Can only be used as a return type • Cannot be changed in sub-classes -
function return_nothing(): void { return null; } V O I
D R E T U R N TY P E -
function return_nothing(): void { return null; } V O I
D R E T U R N TY P E -
function return_nothing(): void { return null; } V O I
D R E T U R N TY P E -
function return_nothing(): void { return null; } V O I
D R E T U R N TY P E -
V O I D R E T U R N
TY P E function return_nothing(): void { return null; } Fatal error: A void function must not return a value (did you mean "return;" instead of "return null;"?) -
V O I D R E T U R N
TY P E function return_nothing(): void { return "nothing"; } Fatal error: A void function must not return a value -
V O I D R E T U R N
TY P E function return_nothing(): void { return; } // or function return_nothing(): void { // no return } -
N U L L A B L E TY P
E S • Allow specified type, or null • Requires an explicit null, doesn’t default to null • Works for Arguments & Return Types • Prefix type with a ? (question mark) -
function hello(string $whom) { echo "Hello " . ($whom ??
"World"); } hello(); N U L L A B L E TY P E S -
function hello(string $whom) { echo "Hello " . ($whom ??
"World"); } hello(); N U L L A B L E TY P E S -
function hello(string $whom) { echo "Hello " . ($whom ??
"World"); } hello(); N U L L A B L E TY P E S -
function hello(?string $whom) { echo "Hello " . ($whom ??
"World"); } hello(); N U L L A B L E TY P E S -
function hello(?string $whom) { echo "Hello " . ($whom ??
"World"); } hello(); N U L L A B L E TY P E S -
N U L L A B L E TY P
E S function hello(?string $whom) { echo "Hello " . ($whom ?? "World"); } hello(); Fatal error: Uncaught Error: Too few arguments to function hello(), 0 passed in <file> on line 6 and exactly 1 expected in <file>:2 -
N U L L A B L E TY P
E S function hello(?string $whom) { echo "Hello " . ($whom ?? "World"); } hello(); -
N U L L A B L E TY P
E S function hello(?string $whom) { echo "Hello " . ($whom ?? "World"); } hello(null); -
N U L L A B L E TY P
E S function hello(?string $whom) { echo "Hello " . ($whom ?? "World"); } hello(null); -
N U L L A B L E TY P
E S function hello(?string $whom { echo "Hello " . ($whom ?? "World"); } hello( ) ); null -
N U L L A B L E TY P
E S function hello(?string $whom { echo "Hello " . ($whom ?? "World"); } hello( = null) ); -
N U L L A B L E R E
T U R N TY P E S -
N U L L A B L E TY P
E S function hello(?string $whom): string { if ($whom !== null) { return "Hello $whom"; } } echo hello("World"); // Hello World -
N U L L A B L E TY P
E S function hello(?string $whom): string { if ($whom !== null) { return "Hello $whom"; } } echo hello("World"); // Hello World -
function hello(?string $whom): string { if ($whom !== null) {
return "Hello $whom"; } } echo hello("World"); // Hello World N U L L A B L E TY P E S -
function hello(?string $whom): string { if ($whom !== null) {
return "Hello $whom"; } } echo hello("World"); // Hello World N U L L A B L E TY P E S -
N U L L A B L E TY P
E S function hello(?string $whom): string { if ($whom !== null) { return "Hello $whom"; } } echo hello(null); -
N U L L A B L E TY P
E S TypeError: Return value of hello() must be of the type string, none returned -
N U L L A B L E TY P
E S function hello(?string $whom): string { if ($whom !== null) { return "Hello $whom"; } } echo hello(null); -
N U L L A B L E TY P
E S function hello(?string $whom): ?string { if ($whom !== null) { return "Hello $whom"; } } echo hello(null); -
N U L L A B L E TY P
E S TypeError: Return value of hello() must be of the type string, none returned -
N U L L A B L E TY P
E S function hello(?string $whom): ?string { if ($whom !== null) { return "Hello $whom"; } return; } echo hello(null); -
N U L L A B L E TY P
E S Fatal error: A function with return type must return a value (did you mean "return null;" instead of "return;"?) -
N U L L A B L E TY P
E S function hello(?string $whom): ?string { if ($whom !== null) { return "Hello $whom"; } return } echo hello(null); ; -
N U L L A B L E TY P
E S function hello(?string $whom): ?string { if ($whom !== null) { return "Hello $whom"; } return } echo hello(null); null; -
N U L L A B L E TY P
E S function hello(?string $whom): ?string { if ($whom !== null) { return "Hello $whom"; } return } echo hello(null); null; // null -
CU R R E N T: P H P 7
. 1 . 0 B E TA 3 -
CU R R E N T LY 2 6 R
FCS ( A N D O N E F O R P H P 8 . 0 ! ) -
6 0 % + M A R K E T
S H A R E -
H U G E P E R FO R M
A N C E W I N S -
M U LT I P L E X I N
G CC-BY: vadikunc -
S E R V E R P US H CC-BY:
Steven Depolo -
N E W A R C H I T E
CT U R E & T E C H N I Q U E S -
A SY N C H R O N O US
/ PA R A L L E L -
W E A R E A CO M M U
N I TY -
M I D - N O V E M B
E R 2 0 1 6 -
T H E F U T U R E I
S A W E S O M E ! CC-BY-SA: Steven Gerner -
M AY B E Y O U ? R E
L E A S E M A N A G E R -
T H A N K YO U ! Twitter: Email:
Slides: @dshafik [email protected] http://daveyshafik.com/slides