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

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

May 15, 2015
Tweet

Transcript

  1. What to Expect When You’re Expecting: PHP 7

  2. Proprietary and Confidential •Community Engineer at Engine Yard •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 Davey Shafik
  3. Let’s start a conversation about mental health in tech mhprompt.org

  4. PHP 7.0

  5. None
  6. Mar 15
 2015 Jun 15
 2015 Oct 15 2015 Feature

    Freeze Finalize Implementation Release Candidates PHP 7.0 Final (We are Here)
  7. Removal of Deprecated Features

  8. Alternative PHP Tags

  9. • ASP Tags: <%, <%= and %> • Script Tags:

    <script language=“php”></script> Alternative PHP Tags
  10. POSIX Compatible Regular Expressions

  11. • All ereg_* functions removed • Use preg_* instead Posix

    Compatible Regular Expressions
  12. ext/mysql

  13. • All mysql_* functions removed • Use mysqli_* for direct

    migration • Use mysqli OO or PDO instead ext/mysql
  14. Multiple Default Cases in Switch

  15. 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 Multiple Default Cases in Switch
  16. Performance

  17. Performance (benchmark.php) 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.941 1.906 1.941 1.941 1.821 1.571 1.559 1.515 1.492 1.414 1.49 1.432 1.492 1.497 1.412 1.367 1.407 1.35 1.302 1.219 1.201 1.159 0.837 0.777
  18. Performance (Wordpress Homepage) 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
  19. 2.4X

  20. 59%

  21. AST Abstract Syntax Tree

  22. AST — Abstract Syntax Tree

  23. • Mostly Invisible to Userland • Paves the way for

    more performance (optimizing is easier with an AST) • Allows for easier implementation of future features AST — Abstract Syntax Tree
  24. Uniform Variable Syntax

  25. • 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. Uniform Variable Syntax
  26. Proprietary and Confidential Uniform Variable Syntax: Consistency Changes 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']()
  27. Uniform Variable Syntax: New Syntax

  28. Proprietary and Confidential $foo()['bar']() [$obj1, $obj2][0]->prop getStr(){0} Missing Combinations

  29. Proprietary and Confidential $foo['bar']::$baz $foo::$bar::$baz $foo->bar()::baz() Nested Static Accessors

  30. Proprietary and Confidential foo()() $foo->bar()() Foo::bar()() $foo()() Nested Parentheses

  31. Proprietary and Confidential (...)['foo'] (...)->foo (...)->foo() (...)::$foo (...)::foo() (...)() Arbitrary

    Expression Dereferencing Including: (function() { ... })() ($obj->closure)()
  32. Proprietary and Confidential "string"->toLower() • Allows for future object-scalars
 [$obj,

    'method']() • Allows array-method callables 'Foo'::$bar • ¯\_()_/¯ Dereferencing Scalars
  33. Proprietary and Confidential global $$foo->bar; // instead use: global ${$foo->bar};

    (or better yet: don’t use globals!) No Longer Supported
  34. Error Handling

  35. Catchable Fatal Error: Call to member function on non-object

  36. • 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. Catchable Fatal Error: Call to member function on non-object
  37. 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
  38. Engine Exceptions

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

    $var = null; $var->method(); } catch (\EngineException $e) { echo $e->getMessage(); 
 // Call to a member function method() on null } echo "Hello World"; // Still runs
  40. • Can be handled gracefully • Finally blocks are called

    • Destructors are called • Easier Catchable fatal error handling Engine Exceptions
  41. \EngineException

  42. • Now throws \EngineExceptions 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) \EngineException
  43. \ParseException

  44. • Now throws \ParseExceptions instead of E_PARSE from eval() or

    include/require \ParseException try { include "parse-error.php"; } catch (\ParseException $e) { var_dump($e); } // parse-error.php
 function $foo() { }
  45. Proprietary and Confidential object(ParseException)#1 (7) { ["message":protected]=> string(84) "syntax error,

    unexpected '$foo' (T_VARIABLE), expecting identifier (T_STRING) or '('" ["string":"BaseException":private]=> string(0) "" ["code":protected]=> int(4) ["file":protected]=> string(17) "engine-exceptions.php" ["line":protected]=> int(2) ["trace":"BaseException":private]=> array(0) { } ["previous":"BaseException":private]=> NULL } \ParseException
  46. \BaseException

  47. • \EngineException does not extend \Exception so that old catch-all’s

    will not catch them, preserving BC • New \BaseException class from which \EngineException, \ParseException, and \Exception extend • catch (\BaseException) { } is the new catch-all. \BaseException
  48. New Features

  49. \o/

  50. Combined Comparison Operator

  51. Spaceship Operator: T_SPACESHIP

  52. • 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 Spaceship Operator:
  53. Proprietary and Confidential // 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; } Spaceship Operator
  54. Unicode Codepoint Escape Syntax

  55. •\u{CODEPOINT} • e.g. ! can be expressed as "\u{1F49A}" Unicode

    Codepoint Escape Syntax
  56. Null Coalesce Operator As close as we’re going to get

    to an ifsetor
  57. • 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; Null Coalesce Operator
  58. Bind Closure on Call

  59. •$Closure->call($object, $closureArgs, $here); • Binds $this/scope to $object • Both

    must be the same • Similar to $Closure->bindTo() or Closure::bind() Bind Closure on Call
  60. Proprietary and Confidential class HelloWorld { private $greeting = "Hello";

    } $closure = function($whom) { echo $this->greeting . ' ' . $whom; } $obj = new HelloWorld(); $closure->call($obj, 'World'); // Hello World Bind Closure on Call
  61. Group Use Declarations

  62. • Simplify multiple use statements with common parent Group Use

    Declarations // 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 };
  63. • Also works for functions and constants: Group Use Statements

    (Cont.) use Framework\Component\{ SubComponent\ClassA, function OtherComponent\someFunction, const OtherComponent\SOME_CONSTANT };
  64. Generator Enhancements

  65. • Generators can now return a value • Retrieved by

    $generator->getReturn() Generator Return Expressions
  66. Proprietary and Confidential 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! Generator Return Values
  67. • Yield other generators or iterable structures — sub-generators •

    Uses yield from Generator Delegation
  68. Generator Delegation function hello() { yield "Hello"; yield " ";

    yield "World!"; yield from goodbye(); } function goodbye() { yield "Goodbye"; yield " "; yield "Moon!"; }
  69. Generator Delegation $gen = hello(); foreach ($gen as $value) {

    echo $value; } 1. "Hello" 2. " " 3. "World!" 4. "Goodbye" 5. " " 6. "Moon!"
  70. Scalar Type Hints

  71. • 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. Scalar Type Hints
  72. Proprietary and Confidential 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) Scalar Type Hints: Non-Strict
  73. • Default non-strict behavior coerces • int(1) => function(int $foo)

    => float(1.0) • float(1.5) => function(int $foo) => int(1.0) • string(“100”) => function (int $foo) => int(100) Scalar Type Hints: Non-Strict
  74. • Strict Type Hints: declare(strict_types=1); • Must be the first

    line • Throws a \TypeException on mis-match declare(strict_types=1); // must be the first line 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 Scalar Type Hints
  75. • 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) Return Type Hints function isValidStatusCode(int $statusCode): bool { return isset($this->statuses[$statusCode]); }
  76. What Next?

  77. • https://github.com/rlerdorf/php7dev • http://gophp7.org/gophp7-ext/ What Next?

  78. Feedback & Questions: 
 Feedback: https://joind.in/
 Twitter: @dshafik Email: davey@engineyard.com

    Slides: http://daveyshafik.com/slides 14534