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

Fee39f0c0ffb29d9ac21607ed188be6b?s=128

Davey Shafik

May 25, 2017
Tweet

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. Let’s start a conversation about mental health in tech mhprompt.org

  5. R E L E A S E M A N

    A G E R
  6. P H P I S D E A D ?

    CC-BY 2.0: Nana B Agyei
  7. 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
  8. C U R R E N T U S A

    G E
  9. P H P U S A G E Source: w3techs

  10. P H P V E R S I O N

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

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

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

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

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

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

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

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

    P E H I N T P H P 5 . 4
  19. T R A I T S P H P 5

    . 4
  20. B U I L T I N C L I

    S E R V E R P H P 5 . 4
  21. 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
  22. 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
  23. 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
  24. F I N A L L Y B L O

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

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

    P H P 5 . 5
  27. 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 !
  28. 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
  29. 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
  30. P H P D B G P H P 5

    . 6
  31. 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
  32. V A R I A D I C S P

    H P 5 . 6
  33. 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
  34. 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
  35. R E M O V E P O S I

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

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

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

    N T A X T R E E P H P 7 . 0
  39. 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
  40. E N G I N E E X C E

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

    A P E S Y N T A X P H P 7 . 0
  42. 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
  43. B I N D C L O S U R

    E O N C A L L P H P 7 . 0
  44. 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
  45. G E N E R A T O R D

    E L E G A T I O N P H P 7 . 0
  46. 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
  47. A N O N Y M O U S C

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

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

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

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

    P E R A T O R P H P 7 . 0
  52. 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
  53. P R E S E N T D A Y

    Credit: NASA/KSC
  54. None
  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
  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 • Throw an exception when too few arguments are passed to a user defined function/method regardless of strict types • Backwards compatibility break
  57. 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
  58. 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
  59. 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
  60. 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
  61. 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
  62. 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
  63. 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();
  64. 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
  65. 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
  66. 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
  67. 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
  68. 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
  69. 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
  70. 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
  71. N E G A T I V E S T

    R I N G O F F S E T S
  72. 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
  73. 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); }
  74. 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); }
  75. 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); }
  76. S E T C H A R A C T

    E R S $string = "abc"; $string[-2] = "z"; // $string == "azc"
  77. 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 }
  78. 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
  79. 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
  80. 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()
  81. C L O S U R E F R O

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

    R S C O P E
  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 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);
  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']; } private function emailValidation($userData) {...} private 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 [$this, 'emailValidation']; } return [$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 [$this, 'emailValidation']; } return [$this, 'genericValidation']; } private function emailValidation($userData) {...} private function genericValidation($userData) {...} } $validator = new Validator(); $callback = $validator->getValidatorCallback('email'); $callback($userData);
  91. 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);
  92. 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);
  93. 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>
  94. 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);
  95. 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);
  96. 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);
  97. 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);
  98. 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);
  99. B E T T E R E R R O

    R H A N D L I N G
  100. 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);
  101. 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);
  102. 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>
  103. 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>
  104. C L A S S C O N S T

    A N T V I S I B I L I T Y
  105. 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; }
  106. 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; }
  107. 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; }
  108. 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; }
  109. 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; }
  110. 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; }
  111. 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
  112. 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() { } }
  113. 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
  114. 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); }
  115. 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); }
  116. 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); }
  117. 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); }
  118. 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); }
  119. 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); }
  120. L I S T ( ) I M P R

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

    K E Y S I N L I S T ( )
  122. S Y D N E Y

  123. 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);
  124. 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
  125. 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
  126. 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);
  127. 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);
  128. 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'
  129. S I N G A P O R E

  130. 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);
  131. 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
  132. 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
  133. 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);
  134. 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);
  135. 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'
  136. A T L A N T A

  137. 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);
  138. 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
  139. 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
  140. 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);
  141. 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);
  142. 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'
  143. S K I P P I N G N U

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

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

    M E R I C K E Y S list( , $lat, $long, , , $name ) = getLocation();
  146. 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();
  147. S H O R T L I S T (

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

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

    ) S Y N T A X ['lat' => $lat, 'long' => $long] = $coords;
  150. 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]];
  151. I T E R A B L E P S

    U E D O T Y P E
  152. 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
  153. 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; } }
  154. 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; } }
  155. 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; }
  156. 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; }
  157. 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; } }
  158. 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());
  159. V O I D R E T U R N

    T Y P E
  160. 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
  161. function return_nothing(): void { return null; } V O I

    D R E T U R N T Y P E
  162. function return_nothing(): void { return null; } V O I

    D R E T U R N T Y P E
  163. function return_nothing(): void { return null; } V O I

    D R E T U R N T Y P E
  164. 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;"?)
  165. 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
  166. 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 }
  167. N U L L A B L E T Y

    P E S
  168. 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)
  169. function hello(string $whom) { echo "Hello " . ($whom ??

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

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

    "World"); } hello(); N U L L A B L E T Y P E S
  172. 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
  173. N U L L A B L E T Y

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

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

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

    "World"); } hello(); N U L L A B L E T Y P E S
  177. 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
  178. N U L L A B L E T Y

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

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

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

    T U R N T Y P E S
  182. 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
  183. 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
  184. 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
  185. 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);
  186. 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
  187. 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);
  188. 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);
  189. 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
  190. 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);
  191. 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);
  192. 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;"?)
  193. 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);
  194. 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
  195. C U R R E N T : P H

    P 7 . 1 . 5
  196. B E Y O N D P H P 7

    . 1
  197. None
  198. 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
  199. 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 ! )
  200. 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 ! )
  201. W E W A N T Y O U !

    Credit: NASA
  202. I N S U M M A R Y

  203. I S G R E A T !

  204. C O M I N G S O O N

    !
  205. T H E F U T U R E I

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

    Email: Slides: https://joind.in/talk/ @dshafik dshafik@akamai.com http://daveyshafik.com/slides f33ff