Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

Davey Shafik

May 15, 2015
Tweet

More Decks by Davey Shafik

Other Decks in Programming

Transcript

  1. 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
  2. Mar 15
 2015 Jun 15
 2015 Oct 15 2015 Feature

    Freeze Finalize Implementation Release Candidates PHP 7.0 Final (We are Here)
  3. • ASP Tags: <%, <%= and %> • Script Tags:

    <script language=“php”></script> Alternative PHP Tags
  4. • All mysql_* functions removed • Use mysqli_* for direct

    migration • Use mysqli OO or PDO instead ext/mysql
  5. 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
  6. 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
  7. 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
  8. 59%

  9. • 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
  10. • 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
  11. 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']()
  12. Proprietary and Confidential (...)['foo'] (...)->foo (...)->foo() (...)::$foo (...)::foo() (...)() Arbitrary

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

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

    (or better yet: don’t use globals!) No Longer Supported
  15. • 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
  16. 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
  17. 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
  18. • Can be handled gracefully • Finally blocks are called

    • Destructors are called • Easier Catchable fatal error handling Engine Exceptions
  19. • 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
  20. • 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() { }
  21. 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
  22. • \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
  23. \o/

  24. • 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:
  25. 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
  26. • 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
  27. •$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
  28. 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
  29. • 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 };
  30. • Also works for functions and constants: Group Use Statements

    (Cont.) use Framework\Component\{ SubComponent\ClassA, function OtherComponent\someFunction, const OtherComponent\SOME_CONSTANT };
  31. • Generators can now return a value • Retrieved by

    $generator->getReturn() Generator Return Expressions
  32. 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
  33. Generator Delegation function hello() { yield "Hello"; yield " ";

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

    echo $value; } 1. "Hello" 2. " " 3. "World!" 4. "Goodbye" 5. " " 6. "Moon!"
  35. • 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
  36. 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
  37. • 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
  38. • 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
  39. • 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]); }