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

    View Slide

  2. h tt p : / /d e v e l o p e r. a ka m a i .co m

    View Slide

  3. Let’s start a conversation about
    mental health in tech
    mhprompt.org

    View Slide

  4. View Slide

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

    View Slide

  6. P H P I S D E A D
    CC-BY 2.0: Nana B Agyei

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  14. J AVA S C R I PT I S W I N N I N G
    2004 2016

    View Slide

  15. J AVA S C R I PT I S
    2004 2016

    View Slide

  16. W H AT A B O U T P H P ?

    View Slide

  17. P H P I S
    Source: Google Trends
    2016
    2004

    View Slide

  18. P H P I S J AVA S C R I PT
    Source: Google Trends
    2016
    2004

    View Slide

  19. N E W L A N G UAG E S A R E W I N N I N G

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  25. G O L A N G V S R UST V S P H P
    2010 2016
    Rust Golang PHP
    Source: Google Trends

    View Slide

  26. M AY B E I T ’ S T H E PA R A D I G M ?

    View Slide

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

    View Slide

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

    View Slide

  29. M AY B E I T ’ S T H E S K I L LS E T !

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  33. R I P H P ?
    CC-BY 2.0: johnny myreng henriksen

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  38. CO N T E XT: 1 2 M O N T H S

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  42. T H I R D - PA RTY E CO SYST E M

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  46. P R E D I CTA B L E & CO N S I ST E N T
    CC-BY-SA: InSapphoWeTrust

    View Slide

  47. L AT E STAT I C B I N D I N G

    View Slide

  48. U N I F O R M VA R I A B L E SY N TA X

    View Slide

  49. L A N G UA G E S P E C I F I C AT I O N

    View Slide

  50. CO N C I S E
    CC-BY 2.0: Dean Hochman

    View Slide

  51. C LO S U R E S

    View Slide

  52. C A L L A B L E S

    View Slide

  53. T R A I TS

    View Slide

  54. G E N E R ATO RS

    View Slide

  55. A N O N Y M O US C L A SS E S

    View Slide

  56. R E L I A B L E
    CC-BY 2.0: mpclemens

    View Slide

  57. S H A R E D - N OT H I N G A R C H I T E CT U R E

    View Slide

  58. P H P- F P M

    View Slide

  59. D E B U G G A B L E
    CC-BY-SA 2.0: Peter Grima

    View Slide

  60. X D E B U G

    View Slide

  61. P H P D B G

    View Slide

  62. P H P I S N OT E VO LV I N G
    CC-BY 2.0: Duncan Hull

    View Slide

  63. S H O RT E C H O TAG S
    P H P 5 . 4

    View Slide

  64. B I N A R Y N U M B E RS
    P H P 5 . 4

    View Slide

  65. S H O RT A R R AY SY N TA X
    P H P 5 . 4

    View Slide

  66. A R R AY D E R E F E R E N C I N G
    P H P 5 . 4

    View Slide

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

    View Slide

  68. C A L L A B L E TY P E H I N T
    P H P 5 . 4

    View Slide

  69. T R A I TS
    P H P 5 . 4

    View Slide

  70. B U I LT I N C L I S E R V E R
    P H P 5 . 4

    View Slide

  71. L I ST S U P P O RT I N FO R E A C H
    P H P 5 . 5

    View Slide

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

    View Slide

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

    View Slide

  74. F I N A L LY B LO C K S
    P H P 5 . 5

    View Slide

  75. E XT/ PA SS W O R D
    P H P 5 . 5

    View Slide

  76. G E N E R ATO RS
    P H P 5 . 5

    View Slide

  77. 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 !

    View Slide

  78. E X P O N E N T O P E R ATO R ( T _ P O W )
    P H P 5 . 6

    View Slide

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

    View Slide

  80. P H P D B G
    P H P 5 . 6

    View Slide

  81. I M P O RT F U N CT I O N S / CO N STA N TS
    P H P 5 . 6

    View Slide

  82. VA R I A D I CS
    P H P 5 . 6

    View Slide

  83. A R G U M E N T U N PAC K I N G ( S P L AT )
    P H P 5 . 6

    View Slide

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

    View Slide

  85. R E M O V E P O S I X R E G E X
    P H P 7 . 0

    View Slide

  86. R E M O V E E XT/ M YS Q L
    P H P 7 . 0

    View Slide

  87. 2 . 4 X FA ST E R
    P H P 7 . 0

    View Slide

  88. A BST R ACT SY N TA X T R E E
    P H P 7 . 0

    View Slide

  89. U N I F O R M VA R I A B L E SY N TA X
    P H P 7 . 0

    View Slide

  90. E N G I N E E XC E PT I O N S
    P H P 7 . 0

    View Slide

  91. U N I CO D E E S C A P E SY N TA X
    P H P 7 . 0

    View Slide

  92. N U L L COA L E S C E O P E R ATO R
    P H P 7 . 0

    View Slide

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

    View Slide

  94. G R O U P US E D E C L A R AT I O N S
    P H P 7 . 0

    View Slide

  95. G E N E R ATO R D E L E G AT I O N
    P H P 7 . 0

    View Slide

  96. G E N E R ATO R R E T U R N VA LU E S
    P H P 7 . 0

    View Slide

  97. A N O N Y M O US C L A SS E S
    P H P 7 . 0

    View Slide

  98. S C A L A R TY P E H I N TS
    P H P 7 . 0

    View Slide

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

    View Slide

  100. ST R I CT TY P E S
    P H P 7 . 0

    View Slide

  101. S PA C E S H I P O P E R ATO R
    P H P 7 . 0

    View Slide

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

    View Slide

  103. T H E F U T U R E
    Credit: NASA/KSC

    View Slide

  104. View Slide

  105. TO O F E W A R G U M E N TS E XC E PT I O N

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  112. 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 on line 6 and defined in on
    line 1

    View Slide

  113. 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 on
    line 4
    Hello

    View Slide

  114. 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();

    View Slide

  115. 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 on line
    6 and exactly 1 expected in :2

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  123. N E G AT I V E ST R I N G O F FS E TS

    View Slide

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

    View Slide

  125. 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);
    }

    View Slide

  126. 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);
    }

    View Slide

  127. 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);
    }

    View Slide

  128. 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);
    }

    View Slide

  129. S E T C H A R A CT E RS
    $string = "abc";
    $string[-2] = "z";
    // $string == "azc"

    View Slide

  130. 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
    }

    View Slide

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

    View Slide

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

    View Slide

  133. 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()

    View Slide

  134. C LO S U R E F R O M C A L L A B L E

    View Slide

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

    {

    ...

    }

    }

    View Slide

  136. C LO S I N G OV E R S CO P E

    View Slide

  137. 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);

    View Slide

  138. 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);

    View Slide

  139. 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);

    View Slide

  140. 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);

    View Slide

  141. 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);

    View Slide

  142. 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);

    View Slide

  143. 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);

    View Slide

  144. 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);

    View Slide

  145. 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);

    View Slide

  146. 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);

    View Slide

  147. 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 :

    View Slide

  148. 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);

    View Slide

  149. 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);

    View Slide

  150. 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);

    View Slide

  151. 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);

    View Slide

  152. 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);

    View Slide

  153. 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);

    View Slide

  154. 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);

    View Slide

  155. B E T T E R E R R O R H A N D L I N G

    View Slide

  156. 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);

    View Slide

  157. 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);

    View Slide

  158. 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 :

    View Slide

  159. 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 :

    View Slide

  160. C L A SS CO N STA N T V I S I B I L I TY

    View Slide

  161. 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;
    }

    View Slide

  162. 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;
    }

    View Slide

  163. 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;
    }

    View Slide

  164. 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;
    }

    View Slide

  165. 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;
    }

    View Slide

  166. 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;
    }

    View Slide

  167. 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;
    }

    View Slide

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

    View Slide

  169. 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() { }
    }

    View Slide

  170. C ATC H I N G M U LT I P L E E XC E PT I O N S

    View Slide

  171. 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);
    }

    View Slide

  172. 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);
    }

    View Slide

  173. 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);
    }

    View Slide

  174. 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);
    }

    View Slide

  175. 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);
    }

    View Slide

  176. 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);
    }

    View Slide

  177. 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);
    }

    View Slide

  178. 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);
    }

    View Slide

  179. L I S T ( ) I M P R OV E M E N TS

    View Slide

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

    View Slide

  181. 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);

    View Slide

  182. 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);

    View Slide

  183. 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);

    View Slide

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

    View Slide

  185. 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);

    View Slide

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

    View Slide

  187. 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);

    View Slide

  188. 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);

    View Slide

  189. 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);

    View Slide

  190. 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'

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  194. 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();

    View Slide

  195. S H O RT L I ST ( ) SY N TA X

    View Slide

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

    View Slide

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

    View Slide

  198. 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]];

    View Slide

  199. I T E R A B L E PS U E D OTY P E

    View Slide

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

    View Slide

  201. 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;
    }
    }

    View Slide

  202. 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;
    }
    }

    View Slide

  203. 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;
    }
    }

    View Slide

  204. 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;
    }

    View Slide

  205. 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;
    }

    View Slide

  206. 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;
    }

    View Slide

  207. 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;
    }
    }

    View Slide

  208. 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());

    View Slide

  209. V O I D R E T U R N TY P E

    View Slide

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

    View Slide

  211. function return_nothing(): void {

    return null;

    }
    V O I D R E T U R N TY P E

    View Slide

  212. function return_nothing(): void {

    return null;

    }
    V O I D R E T U R N TY P E

    View Slide

  213. function return_nothing(): void {

    return null;

    }
    V O I D R E T U R N TY P E

    View Slide

  214. function return_nothing(): void {

    return null;

    }
    V O I D R E T U R N TY P E

    View Slide

  215. 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;"?)

    View Slide

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

    View Slide

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

    }

    View Slide

  218. N U L L A B L E TY P E S

    View Slide

  219. 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)

    View Slide

  220. function hello(string $whom)

    {

    echo "Hello " . ($whom ?? "World");

    }
    hello();
    N U L L A B L E TY P E S

    View Slide

  221. function hello(string $whom)

    {

    echo "Hello " . ($whom ?? "World");

    }
    hello();
    N U L L A B L E TY P E S

    View Slide

  222. function hello(string $whom)

    {

    echo "Hello " . ($whom ?? "World");

    }
    hello();
    N U L L A B L E TY P E S

    View Slide

  223. function hello(?string $whom)

    {

    echo "Hello " . ($whom ?? "World");

    }
    hello();
    N U L L A B L E TY P E S

    View Slide

  224. function hello(?string $whom)

    {

    echo "Hello " . ($whom ?? "World");

    }
    hello();
    N U L L A B L E TY P E S

    View Slide

  225. 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 on line
    6 and exactly 1 expected in :2

    View Slide

  226. N U L L A B L E TY P E S
    function hello(?string $whom)

    {

    echo "Hello " . ($whom ?? "World");

    }
    hello();

    View Slide

  227. N U L L A B L E TY P E S
    function hello(?string $whom)

    {

    echo "Hello " . ($whom ?? "World");

    }
    hello(null);

    View Slide

  228. N U L L A B L E TY P E S
    function hello(?string $whom)

    {

    echo "Hello " . ($whom ?? "World");

    }
    hello(null);

    View Slide

  229. N U L L A B L E TY P E S
    function hello(?string $whom

    {

    echo "Hello " . ($whom ?? "World");

    }
    hello(
    )
    );
    null

    View Slide

  230. N U L L A B L E TY P E S
    function hello(?string $whom

    {

    echo "Hello " . ($whom ?? "World");

    }
    hello(
    = null)
    );

    View Slide

  231. N U L L A B L E R E T U R N TY P E S

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  236. 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);

    View Slide

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

    View Slide

  238. 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);

    View Slide

  239. 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);

    View Slide

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

    View Slide

  241. 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);

    View Slide

  242. 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;"?)

    View Slide

  243. 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);
    ;

    View Slide

  244. 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;

    View Slide

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

    View Slide

  246. CU R R E N T: P H P 7 . 1 . 0 B E TA 3

    View Slide

  247. G O T E ST !

    View Slide

  248. B E YO N D P H P 7 . 1

    View Slide

  249. View Slide

  250. 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 ! )

    View Slide

  251. W E W A N T YO U !
    Credit: NASA

    View Slide

  252. View Slide

  253. 6 0 % + M A R K E T S H A R E

    View Slide

  254. H U G E P E R FO R M A N C E W I N S

    View Slide

  255. M U LT I P L E X I N G
    CC-BY: vadikunc

    View Slide

  256. S E R V E R P US H
    CC-BY: Steven Depolo

    View Slide

  257. N E W A R C H I T E CT U R E & T E C H N I Q U E S

    View Slide

  258. A SY N C H R O N O US / PA R A L L E L

    View Slide

  259. W E A R E A CO M M U N I TY

    View Slide

  260. I N S U M M A R Y

    View Slide

  261. M I D - N O V E M B E R 2 0 1 6

    View Slide

  262. T H E F U T U R E I S A W E S O M E !
    CC-BY-SA: Steven Gerner

    View Slide

  263. View Slide

  264. M AY B E Y O U ?
    R E L E A S E M A N A G E R

    View Slide

  265. T H A N K YO U !
    Twitter:
    Email:
    Slides:
    @dshafik
    [email protected]
    http://daveyshafik.com/slides

    View Slide