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

[php[tek] 2017] PHP 7.NEXT: The New Bits

[php[tek] 2017] PHP 7.NEXT: The New Bits

PHP 7.0 is old news, PHP 7.1 is the new hotness. As the first point release in the 7.x series, 7.1 will set the tone for future releases of the highly successful PHP 7.

PHP 7.1 is shaping up to be an even more feature-filled release than 7.0, join me and walk through what's coming up in the most exciting release yet.

Davey Shafik

May 25, 2017
Tweet

More Decks by Davey Shafik

Other Decks in Programming

Transcript

  1. P H P 7 . N E X T :

    T H E N E W B I T S
  2. D A V E Y S H A F I

    K • Developer • Author • Open Source Contributor • @dshafik
  3. h t t p s : / / d e

    v e l o p e r . a k a m a i . c o m
  4. P H P I S D E A D ?

    CC-BY 2.0: Nana B Agyei
  5. W H A T D O E S P R

    O G R E S S L O O K L I K E ? CC-BY 2.0: damon jah
  6. P H P V E R S I O N

    S Source: composer (seld.be)
  7. P H P M A J O R V E

    R S I O N S 5.x 46% 7.x 54%
  8. P H P I S E V O L V

    I N G CC-BY 2.0: Duncan Hull
  9. S H O R T E C H O T

    A G S P H P 5 . 4
  10. B I N A R Y N U M B

    E R S P H P 5 . 4
  11. S H O R T A R R A Y

    S Y N T A X P H P 5 . 4
  12. A R R A Y D E R E F

    E R E N C I N G P H P 5 . 4
  13. C L O S U R E $ T H

    I S B I N D I N G P H P 5 . 4
  14. C A L L A B L E T Y

    P E H I N T P H P 5 . 4
  15. B U I L T I N C L I

    S E R V E R P H P 5 . 4
  16. L I S T S U P P O R

    T I N F O R E A C H P H P 5 . 5
  17. A R B I T R A R Y E

    X P R E S S I O N S U P P O R T F O R E M P T Y ( ) P H P 5 . 5
  18. S T R I N G / A R R

    A Y D E R E F E R E N C I N G P H P 5 . 5
  19. F I N A L L Y B L O

    C K S P H P 5 . 5
  20. E X T / P A S S W O

    R D P H P 5 . 5
  21. G E N E R A T O R S

    P H P 5 . 5
  22. L A N G U A G E S P

    E C I F I C A T I O N T H A N K S F A C E B O O K !
  23. E X P O N E N T O P

    E R A T O R ( T _ P O W ) P H P 5 . 6
  24. C O N S T A N T S C

    A L A R E X P R E S S I O N S P H P 5 . 6
  25. I M P O R T F U N C

    T I O N S / C O N S T A N T S P H P 5 . 6
  26. A R G U M E N T U N

    P A C K I N G ( S P L A T ) P H P 5 . 6
  27. R E M O V E A L T E

    R N A T I V E P H P T A G S P H P 7 . 0
  28. R E M O V E P O S I

    X R E G E X P H P 7 . 0
  29. R E M O V E E X T /

    M Y S Q L P H P 7 . 0
  30. 2 . 4 X F A S T E R

    P H P 7 . 0
  31. A B S T R A C T S Y

    N T A X T R E E P H P 7 . 0
  32. U N I F O R M V A R

    I A B L E S Y N T A X P H P 7 . 0
  33. E N G I N E E X C E

    P T I O N S P H P 7 . 0
  34. U N I C O D E E S C

    A P E S Y N T A X P H P 7 . 0
  35. N U L L C O A L E S

    C E O P E R A T O R P H P 7 . 0
  36. B I N D C L O S U R

    E O N C A L L P H P 7 . 0
  37. G R O U P U S E D E

    C L A R A T I O N S P H P 7 . 0
  38. G E N E R A T O R D

    E L E G A T I O N P H P 7 . 0
  39. G E N E R A T O R R

    E T U R N V A L U E S P H P 7 . 0
  40. A N O N Y M O U S C

    L A S S E S P H P 7 . 0
  41. S C A L A R T Y P E

    H I N T S P H P 7 . 0
  42. R E T U R N H I N T

    S P H P 7 . 0
  43. S T R I C T T Y P E

    S P H P 7 . 0
  44. S P A C E S H I P O

    P E R A T O R P H P 7 . 0
  45. C O M B I N E D C O

    M P A R I S O N O P E R A T O R P H P 7 . 0
  46. P R E S E N T D A Y

    Credit: NASA/KSC
  47. T O O F E W A R G U

    M E N T S E X C E P T I O N
  48. T O O F E W A R G U

    M E N T S E X C E P T 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
  49. function hello($whom) { echo "Hello $whom"; } hello(); 1 2

    3 4 5 6 T O O F E W A R G U M E N T S E X C E P T I O N
  50. function hello($whom) { echo "Hello $whom"; } hello(); 1 2

    3 4 5 6 T O O F E W A R G U M E N T S E X C E P T I O N
  51. function hello($whom) { echo "Hello $whom"; } hello(); 1 2

    3 4 5 6 T O O F E W A R G U M E N T S E X C E P T I O N
  52. function hello($whom) { echo "Hello $whom"; } hello(); 1 2

    3 4 5 6 T O O F E W A R G U M E N T S E X C E P T I O N
  53. function hello($whom) { echo "Hello $whom"; } hello(); 1 2

    3 4 5 6 T O O F E W A R G U M E N T S E X C E P T I O N Warning: Missing argument 1 for hello(), called in <file> on line 6 and defined in <file> on line 1
  54. function hello($whom) { echo "Hello $whom"; } hello(); 1 2

    3 4 5 6 T O O F E W A R G U M E N T S E X C E P T I O N Notice: Undefined variable: what in <file> on line 4 Hello
  55. T O O F E W A R G U

    M E N T S E X C E P T I O N 1 2 3 4 5 6 function hello($whom) { echo "Hello $whom"; } hello();
  56. T O O F E W A R G U

    M E N T S E X C E P T I O N function hello($whom) { echo "Hello $whom"; } hello(); 1 2 3 4 5 6 Fatal error: Uncaught ArgumentCountError: Too few arguments to function hello(), 0 passed in <file> on line 6 and exactly 1 expected in <file>:1
  57. T O O F E W A R G U

    M E N T S E X C E P T I O N function hello($whom) { echo "Hello $whom"; } try { hello(); } catch (\ArgumentCountError $e) { // Handle exception } 1 2 3 4 5 6 7 8 9 10
  58. T O O F E W A R G U

    M E N T S E X C E P T I O N function hello($whom) { echo "Hello $whom"; } try { hello(); } catch (\ArgumentCountError $e) { // Handle exception } 1 2 3 4 5 6 7 8 9 10
  59. T O O F E W A R G U

    M E N T S E X C E P T I O N function hello($whom, $when) { echo "Hello $whom, have a good $when"; } try { $args = ['World']; hello(... $args); } catch (\ArgumentCountError $e) { // Handle exception } 1 2 3 4 5 6 7 8 9 10 11
  60. T O O F E W A R G U

    M E N T S E X C E P T I O N function hello($whom, $when) { echo "Hello $whom, have a good $when"; } try { $args = ['World']; hello(... $args); } catch (\ArgumentCountError $e) { // Handle exception } 1 2 3 4 5 6 7 8 9 10 11
  61. E X C E P T I O N H

    I E R A R C H Y \Throwable interface ├── \Exception implements \Throwable └── \Error implements \Throwable ├── \TypeError extends \Error ├── \ParseError extends \Error └── \AssertionError extends \Error
  62. E X C E P T I O N H

    I E R A R C H Y \Throwable interface ├── \Exception implements \Throwable └── \Error implements \Throwable ├── \TypeError extends \Error │ └── \ArgumentCountError extends \TypeError ├── \ParseError extends \Error └── \AssertionError extends \Error
  63. N E G A T I V E S T

    R I N G O F F S E T S
  64. N E G A T I V E S T

    R I N G O F F S E T S • Consistently support negative string offsets • Similar to substr() • In string character accessors • Internal functions
  65. N E G A T I V E S T

    R I N G O F F S E T S $path = "/path/to/somewhere/"; if (substr($path, -1) !== '/') { $path = substr($path, 0, -1); }
  66. N E G A T I V E S T

    R I N G O F F S E T S $path = "/path/to/somewhere/"; if ($path[-1] === '/') { $path = substr($path, 0, -1); }
  67. N E G A T I V E S T

    R I N G O F F S E T S $path = "/path/to/somewhere/"; if ($path{-1} === '/') { $path = substr($path, 0, -1); }
  68. S E T C H A R A C T

    E R S $string = "abc"; $string[-2] = "z"; // $string == "azc"
  69. C H E C K L E N G T

    H if (strlen($_POST['password']) < 8) { // Do something } if (!isset($_POST['password'][7])) { // Do something } if (!isset($_POST['password'][-8])) { // Do something }
  70. 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 G T H
  71. 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 G T H
  72. F U N C T I O N S U

    P P O R T 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()
  73. C L O S U R E F R O

    M C A L L A B L E
  74. C L O 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 { ... } }
  75. C L O S I N G O V E

    R S C O P E
  76. C L O S I N G O V E

    R S C O 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);
  77. C L O S I N G O V E

    R S C O 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);
  78. C L O S I N G O V E

    R S C O 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);
  79. C L O S I N G O V E

    R S C O 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);
  80. C L O S I N G O V E

    R S C O 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);
  81. C L O S I N G O V E

    R S C O 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);
  82. C L O S I N G O V E

    R S C O 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);
  83. C L O S I N G O V E

    R S C O 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);
  84. C L O S I N G O V E

    R S C O 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);
  85. C L O S I N G O V E

    R S C O P E Fatal error: Uncaught Error: Call to private method Validator::emailValidation() from context '' in <file>:<line>
  86. C L O S I N G O V E

    R S C O 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);
  87. C L O S I N G O V E

    R S C O 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);
  88. C L O S I N G O V E

    R S C O 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);
  89. C L O S I N G O V E

    R S C O 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);
  90. C L O S I N G O V E

    R S C O 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);
  91. B E T T E R E R R O

    R H A N D L I N G
  92. 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);
  93. 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);
  94. 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>
  95. 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>
  96. C L A S S C O N S T

    A N T V I S I B I L I T Y
  97. C L A S S C O N S T

    A N T V I S I B I L I T Y class MyClass { const MY_CONSTANT = 0; const MY_OTHER_CONSTANT = 1; const MY_FAVORITE_CONSTANT = 2; const FOO = 1, BAR = 2; }
  98. C L A S S C O N S T

    A N T V I S I B I L I T Y 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; }
  99. C L A S S C O N S T

    A N T V I S I B I L I T Y 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; }
  100. C L A S S C O N S T

    A N T V I S I B I L I T Y 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; }
  101. C L A S S C O N S T

    A N T V I S I B I L I T Y 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; }
  102. I N T E R F A C E C

    O N S T A N T V I S I B I L I T Y 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; }
  103. E N H A N C E M E N

    T S T O R E F L E C T I O N • Added ReflectionClass->getReflectionConstant() • Added ReflectionClass->getReflectionConstants() • Both return ReflectionClassConstant instances
  104. E N H A N C E M E N

    T S T O R E F L E C T 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() { } }
  105. C A T C H I N G M U

    L T I P L E E X C E P T I O N S
  106. C A T C H I N G M U

    L T I P L E E X C E P T 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); }
  107. C A T C H I N G M U

    L T I P L E E X C E P T 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); }
  108. C A T C H I N G M U

    L T I P L E E X C E P T 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); }
  109. C A T C H I N G M U

    L T I P L E E X C E P T 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); }
  110. C A T C H I N G M U

    L T I P L E E X C E P T 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); }
  111. C A T C H I N G M U

    L T I P L E E X C E P T I O N S try { ... } catch (\PDOException | \My\RequestException $e) { \My\App::renderError(500); } catch (\My\RequestMethodException $e) { \My\App::renderError(405); }
  112. L I S T ( ) I M P R

    O V E M E N T S
  113. S P E C I F Y I N G

    K E Y S I N L I S T ( )
  114. S P E C I F Y I N G

    K E Y S I N L I S T ( ) $coords = [ 'lat' => '33.8688° S', 'long' => '151.2093° E' ]; list($lat, $long) = $coords; var_dump($lat, $long);
  115. S P E C I F Y I N G

    K E Y S I N L I S T ( ) $coords = [ 'lat' => '33.8688° S', 'long' => '151.2093° E' ]; list($lat, $long) = $coords; var_dump($lat, $long); Notice: Undefined offset: 0 Notice: Undefined offset: 1
  116. S P E C I F Y I N G

    K E Y S I N L I S T ( ) $coords = [ 'lat' => '33.8688° S', 'long' => '151.2093° E' ]; list($lat, $long) = $coords; var_dump($lat, $long); $lat === NULL $long === NULL
  117. S P E C I F Y I N G

    K E Y S I N L I S T ( ) $coords = [ 'lat' => '33.8688° S', 'long' => '151.2093° E' ]; list($lat, $long) = $coords; var_dump($lat, $long);
  118. S P E C I F Y I N G

    K E Y S I N L I S T ( ) $coords = [ 'lat' => '33.8688° S', 'long' => '151.2093° E' ]; list('lat' => $lat, 'long' => $long) = $coords; var_dump($lat, $long);
  119. S P E C I F Y I N G

    K E Y S I N L I S T ( ) $coords = [ 'lat' => '33.8688° S', 'long' => '151.2093° E' ]; list('lat' => $lat, 'long' => $long) = $coords; var_dump($lat, $long); $lat === '33.8688° S' $long === '151.2093° E'
  120. S P E C I F Y I N G

    K E Y S I N L I S T ( ) $coords = [ 'lat' => '1.3521° N', 'long' => '103.8198° E' ]; list($lat, $long) = $coords; var_dump($lat, $long);
  121. S P E C I F Y I N G

    K E Y S 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
  122. S P E C I F Y I N G

    K E Y S 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
  123. S P E C I F Y I N G

    K E Y S I N L I S T ( ) $coords = [ 'lat' => '1.3521° N', 'long' => '103.8198° E' ]; list($lat, $long) = $coords; var_dump($lat, $long);
  124. S P E C I F Y I N G

    K E Y S 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);
  125. S P E C I F Y I N G

    K E Y S 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'
  126. S P E C I F Y I N G

    K E Y S I N L I S T ( ) $coords = [ 'lat' => '33.7490° N', 'long' => '84.3880° W' ]; list($lat, $long) = $coords; var_dump($lat, $long);
  127. S P E C I F Y I N G

    K E Y S I N L I S T ( ) $coords = [ 'lat' => '33.7490° N', 'long' => '84.3880° W' ]; list($lat, $long) = $coords; var_dump($lat, $long); Notice: Undefined offset: 0 Notice: Undefined offset: 1
  128. S P E C I F Y I N G

    K E Y S I N L I S T ( ) $coords = [ 'lat' => '33.7490° N', 'long' => '84.3880° W' ]; list($lat, $long) = $coords; var_dump($lat, $long); $lat === NULL $long === NULL
  129. S P E C I F Y I N G

    K E Y S I N L I S T ( ) $coords = [ 'lat' => '33.7490° N', 'long' => '84.3880° W' ]; list($lat, $long) = $coords; var_dump($lat, $long);
  130. S P E C I F Y I N G

    K E Y S I N L I S T ( ) $coords = [ 'lat' => '33.7490° N', 'long' => '84.3880° W' ]; list('lat' => $lat, 'long' => $long) = $coords; var_dump($lat, $long);
  131. S P E C I F Y I N G

    K E Y S I N L I S T ( ) $coords = [ 'lat' => '33.7490° N', 'long' => '84.3880° W' ]; list('lat' => $lat, 'long' => $long) = $coords; var_dump($lat, $long); $lat === '33.7490° N’ $long === '84.3880° W'
  132. S K I P P I N G N U

    M E R I C K E Y S
  133. S K I P P I N G N U

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

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

    M E R I C K E Y S list( 1 => $lat, 2 => $long, 5 => $name ) = getLocation();
  136. S H O R T L I S T (

    ) S Y N T A X
  137. S H O R T L I S T (

    ) S Y N T A X list('lat' => $lat, 'long' => $long) = $coords;
  138. S H O R T L I S T (

    ) S Y N T A X ['lat' => $lat, 'long' => $long] = $coords;
  139. S H O R T L I S T (

    ) S Y N T A X : M U T U A L L Y E X C L U S I V E S Y N T A 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]];
  140. I T E R A B L E P S

    U E D O T Y P E
  141. I T E R A B L E P S

    U E D O T Y 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 • Not generic objects
  142. I T E R A B L E P S

    U E D O T Y P E function enumerate(iterable $args) { foreach ($args as $arg) { echo $args; } }
  143. I T E R A B L E P S

    U E D O T Y P E function enumerate(iterable $args) { foreach ($args as $arg) { echo $args; } }
  144. I T E R A B L E P S

    U E D O T Y P E : R E T U R N T Y P E function compactor(... $args): iterable { return $args; }
  145. I T E R A B L E P S

    U E D O T Y P E : R E T U R N T Y P E function compactor(... $args): iterable { return $args; }
  146. I T E R A B L E P S

    U E D O T Y P E : G E N E R A T O R S function compactor(... $args): iterable { foreach ($args as $arg) { yield $arg; } }
  147. A D D S I S _ I T E

    R A B L E ( ) F U N C T 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());
  148. V O I D R E T U R N

    T Y 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
  149. V O I D R E T U R N

    T Y 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;"?)
  150. V O I D R E T U R N

    T Y P E function return_nothing(): void { return "nothing"; } Fatal error: A void function must not return a value
  151. V O I D R E T U R N

    T Y P E function return_nothing(): void { return; } // or function return_nothing(): void { // no return }
  152. N U L L A B L E T Y

    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)
  153. function hello(string $whom) { echo "Hello " . ($whom ??

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

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

    "World"); } hello(); N U L L A B L E T Y P E S
  156. N U L L A B L E T Y

    P E S function hello(string $whom) { echo "Hello " . ($whom ?? "World"); } hello(); Fatal error: Uncaught ArgumentCountError: Too few arguments to function hello(), 0 passed in <file> on line 6 and exactly 1 expected in <file>:1
  157. N U L L A B L E T Y

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

    P E S function hello(string $whom = null) { echo "Hello " . ($whom ?? "World"); } hello();
  159. function hello(?string $whom) { echo "Hello " . ($whom ??

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

    "World"); } hello(); N U L L A B L E T Y P E S
  161. N U L L A B L E T Y

    P E S function hello(?string $whom) { echo "Hello " . ($whom ?? "World"); } hello(); Fatal error: Uncaught ArgumentCountError: Too few arguments to function hello(), 0 passed in <file> on line 6 and exactly 1 expected in <file>:1
  162. N U L L A B L E T Y

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

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

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

    T U R N T Y P E S
  166. N U L L A B L E T Y

    P E S function hello(?string $whom): string { if ($whom !== null) { return "Hello $whom"; } } echo hello("World"); // Hello World
  167. function hello(?string $whom): string { if ($whom !== null) {

    return "Hello $whom"; } } echo hello("World"); // Hello World N U L L A B L E T Y P E S
  168. function hello(?string $whom): string { if ($whom !== null) {

    return "Hello $whom"; } } echo hello("World"); // Hello World N U L L A B L E T Y P E S
  169. N U L L A B L E T Y

    P E S function hello(?string $whom): string { if ($whom !== null) { return "Hello $whom"; } } echo hello(null);
  170. N U L L A B L E T Y

    P E S TypeError: Return value of hello() must be of the type string, none returned
  171. N U L L A B L E T Y

    P E S function hello(?string $whom): string { if ($whom !== null) { return "Hello $whom"; } } echo hello(null);
  172. N U L L A B L E T Y

    P E S function hello(?string $whom): ?string { if ($whom !== null) { return "Hello $whom"; } } echo hello(null);
  173. N U L L A B L E T Y

    P E S TypeError: Return value of hello() must be of the type string, none returned
  174. N U L L A B L E T Y

    P E S function hello(?string $whom): ?string { if ($whom !== null) { return "Hello $whom"; } } echo hello(null);
  175. N U L L A B L E T Y

    P E S function hello(?string $whom): ?string { if ($whom !== null) { return "Hello $whom"; } return; } echo hello(null);
  176. N U L L A B L E T Y

    P E S Fatal error: A function with return type must return a value (did you mean "return null;" instead of "return;"?)
  177. N U L L A B L E T Y

    P E S function hello(?string $whom): ?string { if ($whom !== null) { return "Hello $whom"; } return; } echo hello(null);
  178. N U L L A B L E T Y

    P E S function hello(?string $whom): ?string { if ($whom !== null) { return "Hello $whom"; } return null; } echo hello(null); // null
  179. C U R R E N T : P H

    P 7 . 1 . 5
  180. C U R R E N T L Y 1

    5 R F C S I M P L E M E N T E D
  181. 8 M O R E A C C E P

    T E D ( A N D O N E F O R P H P 8 . 0 ! )
  182. 1 4 M O R E I N D I

    S C U S S I O N ( A N D A N O T H E R O N E F O R P H P 8 . 0 ! )
  183. W E W A N T Y O U !

    Credit: NASA
  184. T H E F U T U R E I

    S A W E S O M E ! CC-BY-SA: Steven Gerner
  185. F E E D B A C K Feedback: Twitter:

    Email: Slides: https://joind.in/talk/ @dshafik [email protected] http://daveyshafik.com/slides f33ff