[PHPKonf 2015] What to Expect When You're Expecting: PHP 7

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

July 26, 2015
Tweet

Transcript

  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: G
  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. h t t p : / / 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. P H P 7 . 0 CC-BY:

  6. None
  7. Vincent PONTIER

  8. Mar 15
 2015 Jun 15
 2015 Oct 15 2015 Feature

    Freeze Finalize Implementation Release Candidates PHP 7.0 Final Alphas/Betas (we are here)
  9. W H AT H A P P E N E

    D T O 6 ?
  10. 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. 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:
  12. A LT E R N AT I V E P

    H P TA G S
  13. 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. 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:
  15. 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. E X T / M Y S Q L CC-BY:

  17. E X T / M Y S Q L •

    All mysql_* functions removed • Use mysqli_* for direct migration • Use mysqli OO or PDO instead
  18. 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. 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. P E R F O R M A N C

    E CC-BY-SA:
  21. 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. 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. 2 . 4 X CC-BY:

  24. 5 9 % CC-BY:

  25. A S T A B S T R A C

    T S Y N TA X T R E E CC-BY:
  26. 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
  27. 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
  28. U N I F O R M VA R I

    A B L E S Y N TA X CC-BY-ND:
  29. 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.
  30. 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']() $var->$prop['key']() $var->{$prop['key']}() ($var->$prop)['key']() Class::$var['key']() Class::{$var['key']}() (Class::$var)['key']()
  31. 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
  32. 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}
  33. 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()
  34. N E S T E D PA R E N

    T H E S E S foo()() $foo->bar()() Foo::bar()() $foo()()
  35. 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)()
  36. 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 • ¯\_(ツ)_/¯
  37. 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!)
  38. A S S E R T I O N S

  39. 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
  40. 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
  41. 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
  42. E R R O R H A N D L

    I N G CC-BY-SA:
  43. 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
  44. 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.
  45. 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
  46. E N G I N E E X C E

    P T I O N S
  47. 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
  48. 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
  49. 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
  50. \ 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
  51. \ E R R O R

  52. \ 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)
  53. \ P A R S E E R R O

    R
  54. \ 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() { }
  55. \ 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 }
  56. \ T Y P E E R R O R

  57. \ 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); }
  58. \ 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 }
  59. \ A S S E R T I O N

    E R R O R
  60. 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
  61. \ 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 }
  62. N E W F E AT U R E S

    CC-BY-SA:
  63. C O M B I N E D C O

    M PA R I S O N O P E R AT O R
  64. 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:
  65. 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
  66. 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; }
  67. 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
  68. 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}"
  69. N U L L C O A L E S

    C E O P E R AT O R Attribution
  70. 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;
  71. B I N D C L O S U R

    E O N C A L L
  72. 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
  73. 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
  74. G R O U P U S E D E

    C L A R AT I O N S CC-BY:
  75. 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 };
  76. G R O U P U S E S TAT

    E M E N T S ( C O N T. ) •Also works for functions and constants: use Framework\Component\{ SubComponent\ClassA, function OtherComponent\someFunction, const OtherComponent\SOME_CONSTANT };
  77. G E N E R AT O R E N

    H A N C E M E N T S CC-BY:
  78. 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()
  79. 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!
  80. 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
  81. 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!"; }
  82. 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!"
  83. A N O N Y M O U S C

    L A S S E S CC-BY:
  84. 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
  85. 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; };
  86. 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
  87. S C A L A R T Y P E

    H I N T S XKCD #1537
  88. 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.
  89. 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)
  90. 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)
  91. 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
  92. 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]); }
  93. W H AT N E X T ?

  94. 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
  95. W H AT N E X T ? http://daveyshafik.com/php7

  96. F E E D B A C K & Q

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