Slide 1

Slide 1 text

What to Expect When You’re Expecting: PHP 7

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

PHP 7.0

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

Mar 15
 2015 Jun 15
 2015 Oct 15 2015 Feature Freeze Finalize Implementation Release Candidates PHP 7.0 Final (We are Here)

Slide 7

Slide 7 text

Removal of Deprecated Features

Slide 8

Slide 8 text

Alternative PHP Tags

Slide 9

Slide 9 text

• ASP Tags: <%, <%= and %> • Script Tags: Alternative PHP Tags

Slide 10

Slide 10 text

POSIX Compatible Regular Expressions

Slide 11

Slide 11 text

• All ereg_* functions removed • Use preg_* instead Posix Compatible Regular Expressions

Slide 12

Slide 12 text

ext/mysql

Slide 13

Slide 13 text

• All mysql_* functions removed • Use mysqli_* for direct migration • Use mysqli OO or PDO instead ext/mysql

Slide 14

Slide 14 text

Multiple Default Cases in Switch

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

Performance

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

2.4X

Slide 20

Slide 20 text

59%

Slide 21

Slide 21 text

AST Abstract Syntax Tree

Slide 22

Slide 22 text

AST — Abstract Syntax Tree

Slide 23

Slide 23 text

• 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

Slide 24

Slide 24 text

Uniform Variable Syntax

Slide 25

Slide 25 text

• 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

Slide 26

Slide 26 text

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']()

Slide 27

Slide 27 text

Uniform Variable Syntax: New Syntax

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

Proprietary and Confidential (...)['foo'] (...)->foo (...)->foo() (...)::$foo (...)::foo() (...)() Arbitrary Expression Dereferencing Including: (function() { ... })() ($obj->closure)()

Slide 32

Slide 32 text

Proprietary and Confidential "string"->toLower() • Allows for future object-scalars
 [$obj, 'method']() • Allows array-method callables 'Foo'::$bar • ¯\_()_/¯ Dereferencing Scalars

Slide 33

Slide 33 text

Proprietary and Confidential global $$foo->bar; // instead use: global ${$foo->bar}; (or better yet: don’t use globals!) No Longer Supported

Slide 34

Slide 34 text

Error Handling

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

• 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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

Engine Exceptions

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

• Can be handled gracefully • Finally blocks are called • Destructors are called • Easier Catchable fatal error handling Engine Exceptions

Slide 41

Slide 41 text

\EngineException

Slide 42

Slide 42 text

• 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

Slide 43

Slide 43 text

\ParseException

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

\BaseException

Slide 47

Slide 47 text

• \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

Slide 48

Slide 48 text

New Features

Slide 49

Slide 49 text

\o/

Slide 50

Slide 50 text

Combined Comparison Operator

Slide 51

Slide 51 text

Spaceship Operator: T_SPACESHIP

Slide 52

Slide 52 text

• 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:

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

Unicode Codepoint Escape Syntax

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

Null Coalesce Operator As close as we’re going to get to an ifsetor

Slide 57

Slide 57 text

• 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

Slide 58

Slide 58 text

Bind Closure on Call

Slide 59

Slide 59 text

•$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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

Group Use Declarations

Slide 62

Slide 62 text

• 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 };

Slide 63

Slide 63 text

• Also works for functions and constants: Group Use Statements (Cont.) use Framework\Component\{ SubComponent\ClassA, function OtherComponent\someFunction, const OtherComponent\SOME_CONSTANT };

Slide 64

Slide 64 text

Generator Enhancements

Slide 65

Slide 65 text

• Generators can now return a value • Retrieved by $generator->getReturn() Generator Return Expressions

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

• Yield other generators or iterable structures — sub-generators • Uses yield from Generator Delegation

Slide 68

Slide 68 text

Generator Delegation function hello() { yield "Hello"; yield " "; yield "World!"; yield from goodbye(); } function goodbye() { yield "Goodbye"; yield " "; yield "Moon!"; }

Slide 69

Slide 69 text

Generator Delegation $gen = hello(); foreach ($gen as $value) { echo $value; } 1. "Hello" 2. " " 3. "World!" 4. "Goodbye" 5. " " 6. "Moon!"

Slide 70

Slide 70 text

Scalar Type Hints

Slide 71

Slide 71 text

• 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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

• 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

Slide 74

Slide 74 text

• 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

Slide 75

Slide 75 text

• 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]); }

Slide 76

Slide 76 text

What Next?

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

Feedback & Questions: 
 Feedback: https://joind.in/
 Twitter: @dshafik Email: [email protected] Slides: http://daveyshafik.com/slides 14534