Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[PHPConf.Asia 2016] Keynote: PHP Is Dead

[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
Tweet

More Decks by Davey Shafik

Other Decks in Programming

Transcript

  1. P H P CO N F. A S I A

    K E Y N OT E CC-BY-ND 2.0: Michaela Loheit
  2. h tt p : / /d e v e l

    o p e r. a ka m a i .co m
  3. P H P I S D E A D CC-BY

    2.0: Nana B Agyei
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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
  9. 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
  10. J AVA S C R I PT I S T

    H E F U T U R E
  11. J AVA S C R I PT I S W

    I N N I N G 2004 2016
  12. P H P I S J AVA S C R

    I PT Source: Google Trends 2016 2004
  13. N E W L A N G UAG E S

    A R E W I N N I N G
  14. R UST I S W I N N I N

    G 2012 2016 Source: Google Trends
  15. R UST I S W I N N I N

    G 2012 2016 Source: Google Trends
  16. G O L A N G I S W I

    N N I N G Source: Google Trends 2010 2016
  17. G O L A N G I S W I

    N N I N G 2010 2016 Source: Google Trends
  18. G O L A N G V S R UST

    2010 2016 Golang Rust Source: Google Trends
  19. G O L A N G V S R UST

    V S P H P 2010 2016 Rust Golang PHP Source: Google Trends
  20. M AY B E I T ’ S T H

    E PA R A D I G M ?
  21. 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
  22. 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
  23. M AY B E I T ’ S T H

    E S K I L LS E T !
  24. 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
  25. 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
  26. 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
  27. 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
  28. 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
  29. 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
  30. 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
  31. 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
  32. 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
  33. 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
  34. 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
  35. 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
  36. 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
  37. P R E D I CTA B L E &

    CO N S I ST E N T CC-BY-SA: InSapphoWeTrust
  38. U N I F O R M VA R I

    A B L E SY N TA X
  39. L A N G UA G E S P E

    C I F I C AT I O N
  40. S H A R E D - N OT H

    I N G A R C H I T E CT U R E
  41. D E B U G G A B L E

    CC-BY-SA 2.0: Peter Grima
  42. P H P I S N OT E VO LV

    I N G CC-BY 2.0: Duncan Hull
  43. B I N A R Y N U M B

    E RS P H P 5 . 4
  44. S H O RT A R R AY SY N

    TA X P H P 5 . 4
  45. A R R AY D E R E F E

    R E N C I N G P H P 5 . 4
  46. C LO S U R E $ T H I

    S B I N D I N G P H P 5 . 4
  47. C A L L A B L E TY P

    E H I N T P H P 5 . 4
  48. B U I LT I N C L I S

    E R V E R P H P 5 . 4
  49. L I ST S U P P O RT I

    N FO R E A C H P H P 5 . 5
  50. 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
  51. 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
  52. F I N A L LY B LO C K

    S P H P 5 . 5
  53. 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 !
  54. E X P O N E N T O P

    E R ATO R ( T _ P O W ) P H P 5 . 6
  55. 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
  56. I M P O RT F U N CT I

    O N S / CO N STA N TS P H P 5 . 6
  57. A R G U M E N T U N

    PAC K I N G ( S P L AT ) P H P 5 . 6
  58. 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
  59. R E M O V E P O S I

    X R E G E X P H P 7 . 0
  60. R E M O V E E XT/ M YS

    Q L P H P 7 . 0
  61. A BST R ACT SY N TA X T R

    E E P H P 7 . 0
  62. U N I F O R M VA R I

    A B L E SY N TA X P H P 7 . 0
  63. E N G I N E E XC E PT

    I O N S P H P 7 . 0
  64. U N I CO D E E S C A

    P E SY N TA X P H P 7 . 0
  65. N U L L COA L E S C E

    O P E R ATO R P H P 7 . 0
  66. B I N D C LO S U R E

    O N C A L L P H P 7 . 0
  67. G R O U P US E D E C

    L A R AT I O N S P H P 7 . 0
  68. G E N E R ATO R D E L

    E G AT I O N P H P 7 . 0
  69. G E N E R ATO R R E T

    U R N VA LU E S P H P 7 . 0
  70. A N O N Y M O US C L

    A SS E S P H P 7 . 0
  71. S C A L A R TY P E H

    I N TS P H P 7 . 0
  72. R E T U R N H I N TS

    P H P 7 . 0
  73. S PA C E S H I P O P

    E R ATO R P H P 7 . 0
  74. 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
  75. TO O F E W A R G U M

    E N TS E XC E PT I O N
  76. 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
  77. 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
  78. 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
  79. 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
  80. 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
  81. 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
  82. 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
  83. 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
  84. 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();
  85. 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
  86. 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
  87. 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
  88. 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
  89. 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
  90. 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
  91. 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
  92. 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
  93. N E G AT I V E ST R I

    N G O F FS E TS
  94. 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
  95. 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); }
  96. 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); }
  97. 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); }
  98. 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); }
  99. S E T C H A R A CT E

    RS $string = "abc"; $string[-2] = "z"; // $string == "azc"
  100. 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 }
  101. 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
  102. 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
  103. 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()
  104. C LO S U R E F R O M

    C A L L A B L E
  105. 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
 {
 ...
 }
 }
  106. 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);
  107. 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);
  108. 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);
  109. 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);
  110. 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);
  111. 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);
  112. 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);
  113. 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);
  114. 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);
  115. 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);
  116. 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>
  117. 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);
  118. 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);
  119. 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);
  120. 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);
  121. 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);
  122. 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);
  123. 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);
  124. B E T T E R E R R O

    R H A N D L I N G
  125. 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);
  126. 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);
  127. 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>
  128. 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>
  129. C L A SS CO N STA N T V

    I S I B I L I TY
  130. 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; }
  131. 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; }
  132. 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; }
  133. 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; }
  134. 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; }
  135. 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; }
  136. 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; }
  137. 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
  138. 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() { } }
  139. C ATC H I N G M U LT I

    P L E E XC E PT I O N S
  140. 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); }
  141. 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); }
  142. 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); }
  143. 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); }
  144. 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); }
  145. 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); }
  146. 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); }
  147. 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); }
  148. L I S T ( ) I M P R

    OV E M E N TS
  149. S P E C I F Y I N G

    K E YS I N L I S T ( )
  150. 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);
  151. 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);
  152. 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);
  153. 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
  154. 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);
  155. 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
  156. 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);
  157. 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);
  158. 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);
  159. 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'
  160. S K I P P I N G N U

    M E R I C K E YS
  161. S K I P P I N G N U

    M E R I C K E YS list( , $lat, $long, , , $name ) = getLocation();
  162. S K I P P I N G N U

    M E R I C K E YS list( , $lat, $long, , , $name ) = getLocation();
  163. 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();
  164. S H O RT L I ST ( ) SY

    N TA X list('lat' => $lat, 'long' => $long) = $coords;
  165. S H O RT L I ST ( ) SY

    N TA X ['lat' => $lat, 'long' => $long] = $coords;
  166. 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]];
  167. I T E R A B L E PS U

    E D OTY P E
  168. 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
  169. 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; } }
  170. 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; } }
  171. 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; } }
  172. 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; }
  173. 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; }
  174. 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; }
  175. 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; } }
  176. 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());
  177. 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
  178. 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;"?)
  179. 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
  180. 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
 }
  181. 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)
  182. function hello(string $whom)
 {
 echo "Hello " . ($whom ??

    "World");
 } hello(); N U L L A B L E TY P E S
  183. function hello(string $whom)
 {
 echo "Hello " . ($whom ??

    "World");
 } hello(); N U L L A B L E TY P E S
  184. function hello(string $whom)
 {
 echo "Hello " . ($whom ??

    "World");
 } hello(); N U L L A B L E TY P E S
  185. function hello(?string $whom)
 {
 echo "Hello " . ($whom ??

    "World");
 } hello(); N U L L A B L E TY P E S
  186. function hello(?string $whom)
 {
 echo "Hello " . ($whom ??

    "World");
 } hello(); N U L L A B L E TY P E S
  187. 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
  188. N U L L A B L E TY P

    E S function hello(?string $whom)
 {
 echo "Hello " . ($whom ?? "World");
 } hello();
  189. N U L L A B L E TY P

    E S function hello(?string $whom)
 {
 echo "Hello " . ($whom ?? "World");
 } hello(null);
  190. N U L L A B L E TY P

    E S function hello(?string $whom)
 {
 echo "Hello " . ($whom ?? "World");
 } hello(null);
  191. N U L L A B L E TY P

    E S function hello(?string $whom
 {
 echo "Hello " . ($whom ?? "World");
 } hello( ) ); null
  192. N U L L A B L E TY P

    E S function hello(?string $whom
 {
 echo "Hello " . ($whom ?? "World");
 } hello( = null) );
  193. N U L L A B L E R E

    T U R N TY P E S
  194. 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
  195. 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
  196. 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
  197. 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
  198. 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);
  199. 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
  200. 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);
  201. 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);
  202. 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
  203. 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);
  204. 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;"?)
  205. 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); ;
  206. 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;
  207. 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
  208. CU R R E N T: P H P 7

    . 1 . 0 B E TA 3
  209. 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 ! )
  210. H U G E P E R FO R M

    A N C E W I N S
  211. M U LT I P L E X I N

    G CC-BY: vadikunc
  212. N E W A R C H I T E

    CT U R E & T E C H N I Q U E S
  213. A SY N C H R O N O US

    / PA R A L L E L
  214. M I D - N O V E M B

    E R 2 0 1 6
  215. T H E F U T U R E I

    S A W E S O M E ! CC-BY-SA: Steven Gerner
  216. M AY B E Y O U ? R E

    L E A S E M A N A G E R
  217. T H A N K YO U ! Twitter: Email:

    Slides: @dshafik [email protected] http://daveyshafik.com/slides