Road runner: PHP7

Lyubomir Filipov  *  Hackafe Plovdiv 2016  *  @FilipovG

Who am I?

Lyubomir Filipov
 

PHP Dev
 

Enthusiast

Skipping version 6

Release cycle of PHP7

Deprecated features

PHP script tags
PHP ASP tags

Removed Alternative PHP Tags

<script language="php">
// Code here
</script>
<%
// Code here
%>
<%=$varToEcho; %>

Removed POSIX-Compatible Regular Expressions

• ereg()
• eregi()
• ereg_replace()
• eregi_replace()
• split()
• spliti()
• sql_regcase()

Changes you will have to make:
 

- add delimiters ( ' / ' )

- using the 'i' modifier
- greediness change

Fatal error: Switch statements may only contain one default clause

Removed Multiple Default Cases in Switches

switch ($expr) {
    default:
        echo "Hello World";
        break;
    default:
        echo "Goodbye Moon!";
        break;
}

Migrating to Procedural mysqli

- switch adapters

Removal of the Original MySQL Extension

Removal of the Original MySQL Extension

Uniform Variable syntax

all variables are evaluated from left to right
// Syntax
$$var['key1']['key2'];
// PHP 5.x:
// Using a multidimensional array value as variable name
${$var['key1']['key2']};
// PHP 7:
// Accessing a multidimensional array within a variable-variable
($$var)['key1']['key2'];


// Syntax
$var->$prop['key'];
// PHP 5.x:
// Using an array value as a property name
$var->{$prop['key']};
// PHP 7:
// Accessing an array within a variable-property
($var->$prop)['key'];

Arbitrary Expression Dereferencing

// Access a static property
(expression)::$foo;
// Call a static method
(expression)::foo();


// Call a callable
(expression)();
// Access a character
(expression){0};

// Define and immediately call a closure without assignment
(function() { /* ... */ })();
// Call a callable within an object property
($obj->callable)();

Dereferencing scalars

// Call a dynamic static method
["className", "staticMethod"]();

// Call a dynamic instance method
[$object, "method"]();

// Use a string scalar as a class name
'className'::staticMethod();

Backward Compatibility Issues

//Changes to the global keyword
global $$foo->bar; // Now a parse error
// instead make sure to add braces to make it unambiguous
global ${$foo->bar};

global will now only take unambiguous variables

Basic Language Changes

Operators

Null Coalesce Operator - ??

$username = $_GET['user'] ?? 'nobody';
// This is equivalent to:
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

Spaceship operator 

echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1

New Stuff

Constant arrays

define('FOO', [
'bar' => 'baz',
'bat' => 'qux'
]);
echo FOO['bar'];

Unpacking Objects Using list()

$object = new \ArrayObject(json_decode($json));
list($foo, $bar, $baz) = $object;

Cryptographically Secure Values

random_bytes ( int $length )

random_int ( int $min , int $max )

Filtered unserialize()

Salts Deprecated in password_hash()

Exceptions on Constructor Failure

try {
    new MessageFormatter('en_US', null);
} catch (\IntlException $e) {
    //handle error
}

internal classes will throw an exception on __construct() failure

Engine exceptions

 all fatal errors and catchable fatal errors are now engine exceptions

we can now handle fatal errors in our code using try...

Engine exceptions

  •  finally blocks are called.
     
  •  Object destructors ( __destruct() ) are called.
     
  • register_shutdown_function() are called.
     
  • Catchable-fatal errors easier to handle.
     
  • Stack trace

Exception Hierarchy

Exception Hierarchy

Fatal error: Class NoBeerException cannot implement
interface Throwable, extend Exception or Error instead

interface CustomExceptionInteface extends \Throwable {
     ...
}

class CustomException 
extends \Exception implements CustomExceptionInteface
{
    // implement interface methods
}

Unicode enhancements

  • Unicode Codepoint Escape Syntax - \u{FF}, \u{00FF}, “🐢” with \u{1F422}
  • New Internationalization Features
IntlChar::charName("\u{1F422}"); \\TURTLE
IntlChar::isAlpha($char);
IntlChar::isAlnum($char);
IntlChar::isPunct($char);

Closure Enhancements

  •  bind closure on call option - With the addition of $this
class A {
    function __construct($val) {
        $this->val = $val;
    }
    function getClosure() {
        //returns closure bound to this object and scope
        return function() { return $this->val; };
    }
}

$ob1 = new A(1);
$ob2 = new A(2);

$cl = $ob1->getClosure();
echo $cl(), "\n"; //1
$cl = $cl->bindTo($ob2); 
echo $cl(), "\n"; //2

Generator Enhancements

  • generator return values
function helloGoodbye() {
    yield "Hello";
    yield " ";
    yield "World!";
    return "Goodbye Moon!";
}

$gen = helloGoodbye();
foreach ($gen as $value) {
    echo $value; // Hello  World!
}

echo $gen->getReturn(); // Goodbye Moon!

 Changes in Object-Oriented  Programming

Context-Sensitive Lexer

callable   and   include   function   trait   global   include_once if   extends   goto   throw   endswitc  implements   instanceof array   finally   static   insteadof   print   for   abstract

interface   echo   foreach   final   namespace   require declare
public   new   require_once   case   protected   or   return   do
private   xor   else   while   const try   elseif   as   enddeclare use   default   catch   endfor   var   break   die   endforeach exit   continue   self   endif   list   switch   parent   endwhile clone   yield   class

 Changes in Object-Oriented  Programming

  • PHP 4 Constructors Deprecated
class foo {
    function foo() {
        echo 'I am the constructor';
    }
}

 Changes in Object-Oriented  Programming

  • Group Use declarations
  • Anonymous Classes
// Pre PHP 7 code
class Logger
{
    public function log($msg)
    {
        echo $msg;
    }
}

$util->setLogger(new Logger());

// PHP 7+ code
$util->setLogger(new class {
    public function log($msg)
    {
        echo $msg;
    }
});

Type hints

Type hints

  • Scalar type hints
  • Coercive Types
  • Strict Types
function hinted(bool $a, float $b, int $c, string $c)
{
}
hinted(true, 4.35, 123, "foo");

Type hints

  • Return Type Hints
function divide(int $a, int $b): int
{
    return $a / $b;
}

Speed Test

  • Use case:
  • - instance with Vagrant (michaelward82/precise64-php7 )
    - zf2-skeleton app
  • - ab test - 1000 calls

Speed Test

Thanks for watching

Road runner: PHP7

By Lyubomir Filipov

Road runner: PHP7

Hackafe Plovdiv 2016

  • 1,410