[PHP South Africa 2015] What To Expect When You're Expecting: PHP 7

[PHP South Africa 2015] What To Expect When You're Expecting: PHP 7

PHP 7 is coming, and with it will come new features, backwards compatibility breaks, and huge performance gains.

This talk will get you prepared for all the changes in this upcoming release and offer practical advice you can implement now to ensure you code still works come upgrade time.

Fee39f0c0ffb29d9ac21607ed188be6b?s=128

Davey Shafik

October 02, 2015
Tweet

Transcript

  1. 1.

    W H AT T O E X P E C

    T W H E N Y O U ’ R E E X P E C T I N G : P H P 7 CC-BY-ND: Greg
  2. 2.

    D AV E Y S H A F I K

    • Author of Zend PHP 5 Certification Study Guide, Sitepoints PHP Anthology: 101 Essential Tips, Tricks & Hacks & PHP Master: Write Cutting Edge Code • A contributor to Zend Framework 1 & 2, phpdoc, & PHP internals • Original creator of PHAR/PHP_Archive • @dshafik
  3. 3.

    h t t p : / / d e v

    e l o p e r. a k a m a i . c o m
  4. 6.
  5. 8.

    Mar 15
 2015 Jun 15
 2015 Oct 15 2015 Feature

    Freeze Finalize Implementation Release Candidates PHP 7.0 Final Alphas/Betas
  6. 9.
  7. 10.
  8. 11.

    W H AT H A P P E N E

    D T O 6 ? var_dump(0x0+1+5);
  9. 12.

    W H AT H A P P E N E

    D T O 6 ? var_dump(0x0+1+5); => ints(7)
  10. 13.

    W H AT H A P P E N E

    D T O 6 ? var_dump(0x0+1+5); => ints(7) •(for PHP 5.3.0 - 5.3.10)
  11. 14.

    R E M O VA L O F D E

    P R E C AT E D F E AT U R E S CC-BY-SA: Shannon Kringen
  12. 15.
  13. 16.

    A LT E R N AT I V E P

    H P TA G S • ASP Tags: <%, <%= and %> • Script Tags: <script language="php"></script>
  14. 17.

    P O S I X C O M PAT I

    B L E R E G U L A R E X P R E S S I O N S CC-BY-SA: InSapphoWeTrust
  15. 18.

    P O S I X C O M PAT I

    B L E R E G U L A R E X P R E S S I O N S • All ereg_* functions removed • Use preg_* instead
  16. 19.
  17. 20.

    E X T / M Y S Q L •

    All mysql_* functions removed • Use mysqli_* for direct migration • Use mysqli OO or PDO instead
  18. 21.

    M U LT I P L E D E FA

    U LT C A S E S I N S W I T C H Copyright © Microsoft
  19. 22.

    M U LT I P L E D E FA

    U LT C A S E S I N S W I T C H <?php switch ($expr) { default: echo "Hello World"; break; default: // only this one would execute echo "Goodbye Moon!"; break; } Fatal error: Switch statements may only contain one default clause
  20. 23.

    P E R F O R M A N C

    E CC-BY-SA: Martin Fisch
  21. 24.

    P E R F O R M A N C

    E ( B E N C H M A R K . P H P ) 0 3,000,000,000 6,000,000,000 9,000,000,000 12,000,000,000 20.01.2014 18.02.2014 21.02.2014 28.02.2014 07.03.2014 14.03.2014 21.03.2014 28.03.2014 04.04.2014 11.04.2014 18.04.2014 25.04.2014 05.05.2014 18.05.2014 26.05.2014 03.06.2014 09.06.2014 30.06.2014 09.07.2014 14.07.2014 15.08.2014 02.09.2014 07.10.2014 21.11.2014 31.12.2014 19.03.2015 30.04.2015 Time (sec) Operations 0.777 0.837 1.159 1.201 1.219 1.302 1.35 1.407 1.367 1.412 1.497 1.492 1.432 1.49 1.414 1.492 1.515 1.559 1.571 1.821 1.941 1.941 1.906 1.941 1.83 1.898 2.115 2.115 1.898 1.83 1.9411.9061.9411.941 1.821 1.5711.559 1.5151.492 1.414 1.49 1.432 1.4921.497 1.412 1.3671.407 1.35 1.302 1.2191.201 1.159 0.837 0.777
  22. 25.

    P E R F O R M A N C

    E ( W O R D P R E S S H O M E PA G E ) 0 2,500,000,000 5,000,000,000 7,500,000,000 10,000,000,000 20.01.2014 04.04.2014 11.04.2014 18.04.2014 25.04.2014 05.05.2014 18.05.2014 26.05.2014 03.06.2014 09.06.2014 30.06.2014 09.07.2014 14.07.2014 15.08.2014 02.09.2014 07.10.2014 21.11.2014 31.12.2014 19.03.2015 30.04.2015 Time (sec) Operations (Wordpress) 11.081 11.756 12.629 13.43 13.89 14.15 14.864 14.81 15.85 15.94 16.54 17.403 18.245 18.913 18.957 20.857 21.503 22.592 23.676 26.756 26.756 23.676 22.592 21.503 20.857 18.957 18.913 18.245 17.403 16.54 15.94 15.85 14.81 14.864 14.15 13.89 13.43 12.629 11.756 11.081
  23. 28.

    A S T A B S T R A C

    T S Y N TA X T R E E CC-BY: Johan Neven
  24. 29.

    Statement Sequence Return while compare op: ≠ branch compare op:

    > assign assign variable: a constant value: 0 variable name: a bin op op: - variable name: a variable name: b variable name: b bin op: op - variable name: b variable name: a Variable name: a condition body variable: a variable: b condition if-body else body
  25. 30.

    A S T — A B S T R A

    C T S Y N TA X T R E E • Mostly Invisible to Userland • Paves the way for more performance (optimizing is easier with an AST) • Allows for easier implementation of future features
  26. 31.

    U N I F O R M VA R I

    A B L E S Y N TA X CC-BY-ND: vil.sandi
  27. 32.

    U N I F O R M VA R I

    A B L E S Y N TA X • Variable-Variables are the problem! • PHP 7 will read left-to-right consistently! • Easy to be forwards compatible with the addition of braces and parenthesis • Lots of new dereferencing options available like nested :: and array-derefenced closures.
  28. 33.

    U N I F O R M VA R I

    A B L E S Y N TA X : C O N S I S T E N C Y C H A N G E S Syntax Old Interpretation New Interpretation $$var['key1']['key2'] ${$var['key1']['key2']} ($$var)['key1']['key2'] $var->$prop['key'] $var->{$prop['key']} ($var->$prop)['key'] $var->$prop['key']() $var->{$prop['key']}() ($var->$prop)['key']() Class::$var['key']() Class::{$var['key']}() (Class::$var)['key']()
  29. 34.

    U N I F O R M VA R I

    A B L E S Y N TA X : N E W S Y N TA X
  30. 35.

    M I S S I N G C O M

    B I N AT I O N S $foo()['bar']() [$obj1, $obj2][0]->prop getStr(){0}
  31. 36.

    N E S T E D S TAT I C

    A C C E S S O R S $foo['bar']::$baz $foo::$bar::$baz $foo->bar()::baz()
  32. 37.

    N E S T E D PA R E N

    T H E S E S foo()() $foo->bar()() Foo::bar()() $foo()()
  33. 38.

    A R B I T R A RY E X

    P R E S S I O N D E R E F E R E N C I N G (...)['foo'] (...)->foo (...)->foo() (...)::$foo (...)::foo() (...)() Including: (function() { ... })() ($obj->closure)()
  34. 39.

    D E R E F E R E N C

    I N G S C A L A R S "string"->toLower() • Allows for future object-scalars
 [$obj, 'method']() • Allows array-method callables 'Foo'::$bar • ¯\_(ϑ)_/¯
  35. 40.

    N O L O N G E R S U

    P P O R T E D global $$foo->bar; // instead use: global ${$foo->bar};
 (or better yet: don’t use globals!)
  36. 42.

    A S S E R T I O N S

    • Behavior of assert() expanded in PHP 7 • Can be turned off, to remove overhead in production • Can emit exceptions on failure, defaults to a WARNING • Allow for a custom message
  37. 43.

    A S S E R T I O N S

    zend.assertions = 1 ; Enable assertions zend.assertions = 0 ; Disable warning/exceptions zend.assertions = -1; Completely Ignored assert.exception = 1 ; Throw exception on failure
  38. 44.

    A S S E R T I O N S

    assert("false === true"); 
 // Not evaluated if zend.assertions = 0 Warning: assert(): Assertion "false === true" failed assert("false === true", "Expression was falsey"); 
 // Supply a custom error message Warning: assert(): Expression was falsey: "false === true" failed
  39. 45.

    E R R O R H A N D L

    I N G CC-BY-SA: stallio
  40. 46.

    C AT C H A B L E FATA L

    E R R O R : C A L L T O M E M B E R F U N C T I O N O N N O N - O B J E C T
  41. 47.

    C AT C H A B L E FATA L

    E R R O R : C A L L T O M E M B E R F U N C T I O N O N N O N - O B J E C T • When calling a method on a non-object it is now a catchable fatal error. • This means you can continue execution if the error is handled.
  42. 48.

    set_error_handler(function($code, $message) { var_dump($code, $message); }); $var = null; $var->method();


    // Fatal Error: Call to a member function method() on null echo "Hello World"; // Still runs Catchable Fatal Error: Call to member function on non-object
  43. 49.

    set_error_handler(function($code, $message) { var_dump($code, $message); }); $var = null; $var->method();


    // Fatal Error: Call to a member function method() on null echo "Hello World"; // Still runs Catchable Fatal Error: Call to member function on non-object
  44. 50.

    E N G I N E E X C E

    P T I O N S
  45. 51.

    Engine Exceptions: Call to member function on non-object 
 try

    { $var = null; $var->method(); } catch (\Error $e) { echo $e->getMessage(); 
 // Call to a member function method() on null } echo "Hello World"; // Still runs
  46. 52.

    E N G I N E E X C E

    P T I O N S • Can be handled gracefully • Finally blocks are called • Destructors are called • Easier Catchable fatal error handling
  47. 53.

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

    \ T H R O WA B L E •

    Engine exceptions do not extend \Exception so that old catch-all’s will not catch them, preserving BC • New \Throwable interface from which \Error and \Exception implement • catch (\Throwable) { } is the new catch-all. • Cannot be implemented in userland — you must extend \Error or \Exception still • \Throwable can itself be extended and implemented
  49. 56.

    \ E R R O R • Now throws \Error

    exceptions instead of Catchable/Fatal errors • No BC break for Fatal (uncaught exception == actually Fatal) • Small BC break for Catchable: no longer possible to suppress errors entirely in set_error_handler() (must catch the exception)
  50. 58.

    \ P A R S E E R R O

    R • Thrown when a parse error is encountered in an include/ require or eval() try { include "parse-error.php"; } catch (\ParseError $e) { var_dump($e); } // parse-error.php function $foo() { }
  51. 59.

    \ P A R S E E R R O

    R object(ParseError)#1 (7) { ["message":protected]=> string(84) "syntax error, 
 unexpected '$foo' (T_VARIABLE), expecting identifier 
 (T_STRING) or '('" ["string":"Error":private]=> string(0) "" ["code":protected]=> int(4) ["file":protected]=> string(21) "/root/parse-error.php" ["line":protected]=> int(2) ["trace":"Error":private]=> array(0) {} ["previous":"Error":private]=> NULL }
  52. 61.

    \ T Y P E E R R O R

    • Throws \TypeError on type mis-matches in strict mode function compare(Comparable $a, Comparable $b) { return $a <=> $b; } try { echo compare($obj, $obj2); } catch (\TypeError $e) { var_dump($e); }
  53. 62.

    \ T Y P E E R R O R

    object(TypeError)#1 (7) { ["message":protected]=> string(110) "Argument 1 passed to compare() must 
 be of the type Comparable, int given" ["string":"Error":private]=> string(0) "" ["code":protected]=> int(1) ["file":protected]=> string(20) "/root/type-error.php" ["line":protected]=> int(3) ["trace":"Error":private]=> array(1) { [0]=> array(4) { ["file"]=> string(20) "/root/type-error.php" ["line"]=> int(8) ["function"]=> string(3) "compare" ["args"]=> array(2) { [0]=> … [1]=> … } } } ["previous":"Error":private]=> NULL }
  54. 63.
  55. 64.

    ini_set('zend.assertions', 1); ini_set('assert.exception', 1); try { assert("false === true", "Expression

    was falsey"); } catch (\AssertionError $e) { var_dump($e); } \ A S S E R T I O N E R R O R • Throws \AssertionError on assert() failures
  56. 65.

    \ A S S E R T I O N

    E R R O R object(AssertionError)#1 (7) { ["message":protected]=> string(21) "Expression was falsey" ["string":"Error":private]=> string(0) "" ["code":protected]=> int(1) ["file":protected]=> string(22) "/root/assert-error.php" ["line":protected]=> int(6) ["trace":"Error":private]=> array(1) { [0]=> array(4) { ["file"]=> string(22) "/root/assert-error.php" ["line"]=> int(6) ["function"]=> string(6) "assert" ["args"]=> array(2) { [0]=> string(14) "false === true" [1]=> string(21) "Expression was falsey" } } } ["previous":"Error":private]=> NULL }
  57. 66.

    N E W F E AT U R E S

    CC-BY-SA: Steven Gerner
  58. 67.

    C O M B I N E D C O

    M PA R I S O N O P E R AT O R
  59. 68.

    S PA C E S H I P O P

    E R AT O R : T _ S PA C E S H I P CC-BY: Virgin Galactic/Mark Greenberg
  60. 69.

    S PA C E S H I P O P

    E R AT O R : • First trinary return operator: • Returns -1 if left operand is less than right • Returns 0 if left and right operands are identical • Returns +1 if left operand is greater than right • Originally proposed by me! • Thankfully championed by Andrea Faulds and finally Stas Malyshev • Looks like a spaceship: <=> • Mostly useful for sorting callbacks
  61. 70.

    S PA C E S H I P O P

    E R AT O R // Pre Spacefaring^W PHP 7 function order_func($a, $b) { return ($a < $b) ? -1 : (($a > $b) ? 1 : 0); } // Post PHP 7 function order_func($a, $b) { return $a <=> $b; }
  62. 71.

    U N I C O D E C O D

    E P O I N T E S C A P E S Y N TA X CC-BY: frontriver
  63. 72.

    U N I C O D E C O D

    E P O I N T E S C A P E S Y N TA X •\u{CODEPOINT} •e.g. ! can be expressed as "\u{1F49A}"
  64. 73.

    N U L L C O A L E S

    C E O P E R AT O R Attribution
  65. 74.

    N U L L C O A L E S

    C E O P E R AT O R • Double question mark: ?? • Will return left operand if not null, or the right operand • Will not raise a notice if the left operand is non-existant (like isset()) • Can be nested:
 $conf = $conf ?? $this->conf ?? static::$defaultConf;
  66. 75.

    B I N D C L O S U R

    E O N C A L L
  67. 76.

    B I N D C L O S U R

    E O N C A L L • Similar to $Closure->bindTo() or Closure::bind() • $Closure->call($object, $closureArgs, $here); • Binds $this/scope to $object • Both must be the same
  68. 77.

    B I N D C L O S U R

    E O N C A L L class HelloWorld { private $greeting = "Hello"; } $closure = function($whom) { echo $this->greeting . ' ' . $whom; } $obj = new HelloWorld(); $closure->call($obj, 'World'); // Hello World
  69. 78.

    G R O U P U S E D E

    C L A R AT I O N S CC-BY: Buddy Venturanza
  70. 79.

    G R O U P U S E D E

    C L A R AT I O N S •Simplify multiple use statements with common parent // Original use Framework\Component\SubComponent\ClassA; use Framework\Component\SubComponent\ClassB as ClassC; use Framework\Component\OtherComponent\ClassD; // With Group Use use Framework\Component\{ SubComponent\ClassA, SubComponent\ClassB as ClassC, OtherComponent\ClassD };
  71. 80.

    G R O U P U S E D E

    C L A R AT I O N S ( C O N T. ) •Also works for functions and constants: use Framework\Component\{ SubComponent\ClassA, function OtherComponent\someFunction, const OtherComponent\SOME_CONSTANT };
  72. 81.

    G E N E R AT O R E N

    H A N C E M E N T S CC-BY: Will Folsom
  73. 82.

    G E N E R AT O R R E

    T U R N E X P R E S S I O N S • Generators can now return a value • Retrieved by $generator->getReturn()
  74. 83.

    G E N E R AT O R R E

    T U R N VA L U E S function gen() { yield "Hello"; yield " "; yield "World!"; return "Goodbye Moon!"; } $gen = gen(); foreach ($gen as $value) { echo $value; } // Outputs "Hello" on iteration 1, " " on iterator 2, and "World!" on iteration 3 echo $gen->getReturn(); // Goodbye Moon!
  75. 84.

    G E N E R AT O R D E

    L E G AT I O N • Yield other generators or iterable structures — sub-generators • Uses yield from
  76. 85.

    G E N E R AT O R D E

    L E G AT I O N function hello() { yield "Hello"; yield " "; yield "World!"; yield from goodbye(); } function goodbye() { yield "Goodbye"; yield " "; yield "Moon!"; }
  77. 86.

    G E N E R AT O R D E

    L E G AT I O N $gen = hello(); foreach ($gen as $value) { echo $value; } 1. "Hello" 2. " " 3. "World!" 4. "Goodbye" 5. " " 6. "Moon!"
  78. 87.

    A N O N Y M O U S C

    L A S S E S CC-BY: Toren Monson
  79. 88.

    A N O N Y M O U S C

    L A S S E S • Like closures but for object instances • Uses new class($args) followed by a regular class definition • Can be namespaced • Support inheritance, traits, and interfaces • The internal name is based on it’s address • e.g. class@0x7fa77f271bd0 • If you extend a class, it will use that class as the prefix instead • This means that if you create anonymous classes in a loop it will actually create multiple of the same anonymous class
  80. 89.

    A N O N Y M O U S C

    L A S S E S $obj = new class($args) { public function __construct($args) { ... } }; $obj = new class ($args) extends Foo implements Bar { use Bat; };
  81. 90.

    A N O N Y M O U S C

    L A S S E S foreach ($array as $value) { $instances[] = new class($value) extends ValueObject { ... } } $instance = new class($value) extends ValueObject { ... }; $instances[..] == $instances[..]; // where $value is the same $instances[..] != $instance; // These are different classes and 
 // will never match
  82. 91.

    S C A L A R T Y P E

    H I N T S XKCD #1537
  83. 92.

    S C A L A R T Y P E

    H I N T S • Type-hint function/method arguments • Type-hint return values • Default: non-strict, will coerce types when possible • Allows for strict, applies to that file only, and only to the things it calls (with type-hints), not the things it defines.
  84. 93.

    S C A L A R T Y P E

    H I N T S : N O N - S T R I C T function sendHttpStatus(int $statusCode, 
 string $message) { header('HTTP/1.0 ' .$statusCode. ' ' .$message); }
 sendHttpStatus(404, "File Not Found"); 
 // integer and string passed sendHttpStatus("403", "OK"); 
 // string "403" coerced to int(403)
  85. 94.

    S C A L A R T Y P E

    H I N T S : N O N - S T R I C T • Default non-strict behavior coerces • int(1) => function(float $foo) => float(1.0) • float(1.5) => function(int $foo) => int(1) • string("100") => function (int $foo) => int(100)
  86. 95.

    S C A L A R T Y P E

    H I N T S • Strict Type Hints: declare(strict_types=1); • Must be the first statement (even before namespace) • Throws a \TypeException on mis-match declare(strict_types=1); // must be the first statement try { sendHttpStatus(404, "File Not Found"); sendHttpStatus("403", "OK"); } catch (\TypeException $e) { var_dump($e); } 
 // Argument 1 passed to sendHttpStatus() must be of the type integer, string given
  87. 96.

    R E T U R N T Y P E

    H I N T S • Type hint return values • Allows for all type hints, not just scalars • Suffix argument list with a colon and the hint (same syntax as Hack) function isValidStatusCode(int $statusCode): bool { return isset($this->statuses[$statusCode]); }
  88. 98.

    W H AT N E X T ? • https://github.com/rlerdorf/php7dev

    • https://github.com/janatzend/docker-php7-nightly-build • http://gophp7.org/gophp7-ext/ • https://wiki.php.net/rfc#php_70
  89. 100.

    F E E D B A C K & Q

    U E S T I O N S Feedback: Twitter: Email: Slides: https://joind.in/ @dshafik me@daveyshafik.com http://daveyshafik.com/slides 14835