Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chrome, Safari or Firefox browser.

Phast &
Phurious

Jan Burkl
Zend Solution Consultant
jan@zend.com

http://images-cdn.moviepilot.com/images/c_fill,h_1080,w_1920/t_mp_quality/ufju2q3yi5byarjwtqut/
the-fast-and-furious-franchise-in-it-s-true-chronological-order-tells-a-whole-new-story-347773.jpg




EVOLUTION

PHP 3.0

  • Released: June 1998
  • New Features:
    • Full fledged language
    • Extensions
  • Performance Features:
    • Token Cache
    • Memory Manager

PHP 4.0

  • Released: May 2000
  • New Features:
    • Modularity
    • Sessions
    • Downwards compatibility (!)
  • Performance Features:
    • Zend Engine

PHP 5

  • 5.0: July 2004
    • New Features:
      • New “true“ object model
      • Destructors
      • Exception handling
  • Performance features
    • Be thankful it‘s not slower!
    • Seeds were sown...

PHP Performance Evolution

bench.php (lower is better)

Putting Things in Perspective

PHP 6

PHP 6 = PHP 5 + Unicode

What Ended Up Happening

Bonus: Roughly doubled memory footprint.

THE End

Time of Death

March 11, 2010

http://bit.ly/php6whathappened

PHP 7

Leading up to PHP 7

2012: Research PHP+JIT begins, led by Dmitry Stogov

2014: No performance gains realized for real-world workloads

Birth of PHPNG

What Made the Difference?




PHP 7

What can we expect?

5.6 vs. 7.0

Real World Application Benchmarks

(% improvement vs. PHP 5.6)

It’s gotten consistently faster with more to come!

What's
new?
http://images4.fanpop.com/image/photos/15000000/Seven-seven-of-nine-15093083-2560-1600.jpg

Uniform Variable Syntax




$foo->bar()();
  • $foo is an object
  • bar() is a method that returns a callable
  • The callable is automatically executed
$foo()[‘bar’]();
  • $foo is a method that returns an array.
  • ['bar'] is an element in the array returned by $foo()
  • ['bar'] contains a callable as it’s value
  • () calls the callable contained in ['bar']
function getStr()
{
    return 'Jan Burkl';
}
echo getStr(){4}; // 'B'

Double $ in referencing globals are no longer supported.

global $$foo->bar;
//No longer supported

There are no longer any restrictions on nesting of dereferencing operations. All of these are now supported:

$obj1 = new StdClass();
$obj1->name = 'Barbara';
$obj2 = new StdClass();
$obj2->name = 'Jan';
$returnVal = [$obj1, $obj2][0]->name;
  • Reference a property statically from a class reference

    $foo['bar']::$baz
  • Statically access a nested referenced property

    $foo::$bar::$baz
  • Call a referenced method statically from a class reference returned by a method.

    $foo->bar()::baz()


Old Meaning New Meaning
$$foo['bar']['baz'] ${$foo['bar']['baz']} ($$foo)['bar']['baz']
$foo->$bar['baz'] $foo->{$bar['baz']} ($foo->$bar)['baz']
$foo->$bar['baz']() $foo->{$bar['baz']}() ($foo->$bar)['baz']()
Foo::$bar['baz']() Foo::{$bar['baz']}() (Foo::$bar)['baz']()

Spaceship

Combined Comparison




  • PHP’s first trinary operator
echo 1<=>2; // -1
echo 1<=>1; // 0
echo 2<=>1; // 1

Arrays

echo [] <=> [];               //  0
echo [1, 2, 3] <=> [1, 2, 3]; //  0
echo [1, 2, 3] <=> [];        //  1
echo [1, 2, 3] <=> [1, 2, 1]; //  1
echo [1, 2, 3] <=> [1, 2, 4]; // -1

Objects

$a = (object) ["a" => "b"];
$b = (object) ["a" => "c"];
echo $a <=> $b; // -1

$a = (object) ["a" => "b"];
$b = (object) ["a" => "b"];
echo $a <=> $b; // 0

usort()

$array = ['oranges', 'apples',
          'bananas', 'grapes'];
usort($array,
  function ($left,$right) {
    return $left<=>$right;
  }
);

Array (
    [0] => apples
    [1] => bananas
    [2] => grapes
    [3] => oranges
)

Anonymous Classes




$obj = new class($i) {
    public function __construct($i) {
        $this->i = $i;
    };
}
(new class extends ConsoleProgram {
    public function main() {
       /* ... */
    }
})->bootstrap();
return new class($controller)
    implements Page {

    public function
        __construct($controller) {
        /* ... */
    }
    /* ... */
};
$pusher->setLogger(new class {
    public function log($msg) {
        print_r($msg . "\n");
    }
});

Caveats, warning, and compatibility

  • Inheritance works as expected
  • Traits work as expected
  • Reflection now has ReflectionClass::isAnonymous() method
  • Serialization will not work, just like with anonymous functions

Generator Return Expressions




function foo() {
    $returnValue = 1;
    yield 1;
    $returnValue = 2;
    yield 2;
    return $returnValue;
}

$bar = foo();




foreach ($bar as $element) {
    echo $element, "\n";
}

var_dump($bar->getReturn());

// 1
// 2
// int(2)

Generator Delegation




function foo() {
    yield 1;
    yield 2;
}
function both() {
    yield from foo();
    yield from [2, 3, 4];
    yield "done"
}




$a = both();

foreach ($a as $value) {
    echo $value . "\n";
}

Filtered unserialize()




// this will unserialize everything
// as before
$data = unserialize($foo);




// this will convert all objects into
// __PHP_Incomplete_Class object
$data = unserialize(
    $foo,
    ["allowed_classes" => false]
);




// converts all objects except MyClass
// into __PHP_Incomplete_Class object
$data = unserialize(
    $foo,
    ["allowed_classes" => [
        "MyClass"
    ]);




//accept all classes as in default
$data = unserialize(
    $foo,
    ["allowed_classes" => true]
);

Throwable Interface

Exceptions in the engine




try {
    do_something(null); // oops!
} catch (\Error $e) {
    echo "Err: {$e->getMessage()}\n";
}

// Error: Call to a member function
// method() on a non-object
  • interface Throwable
    • Exception implements Throwable
    • Error implements Throwable
      • TypeError extends Error
      • ParseError extends Error
function add(int $left, int $right) {
    return $left + $right;
}
try {
    echo add('left', 'right');
} catch (\TypeError $e) {
    // Log error and end gracefully
} catch (\Exception $e) {
    // Handle any exceptions
} catch (\Throwable $e) {
    // Handle everything else
}

ParseError

  • Thrown when you have a parse error in your code
  • Will not allow bad code to run at compile time.
  • Will be thrown if you have a parse error in an eval()
  • Will be thrown if you have a parse error in a file that is included during execution.
$code = 'var_dup($admin);';

try {
    $result = eval($code);
} catch (\ParseError $error) {
    // Handle $error
}
if ($admin) {
    try {
        include "./issue_code.php";
    } catch (\ParseError $error) {
        // Handle $error
    }
}

Benefits

  • finally gets called
  • __destruct() gets called.
  • Fully backwardly compatible

Null Coalesce Operator




$name = $firstName ?? "Jan";
$name .=  " ";
$name .= $lastName ?? "Burkl";
$this->maxCount = is_null(
    $input->getOption('count'))
    ? -1 : $input->getOption('count');
$this->maxCount =
    $input->getOption('count') ?? -1;
$x = NULL;
$y = NULL;
$z = 3;

var_dump($x ?? $y ?? $z); // int(3)

Scalar Type Hints




  • int
  • float
  • string
  • bool
function add(float $a, float $b) {
    return $a + $b;
}

$returnValue = add(1.5, 2.5);
// int(4)
// Works
$returnValue = add("1 foo", "2");
// PHP 5.6 and below gives a Notice
// PHP7 TypeError

$returnValue = add(1, 2); // int(3)
// Widening

Widening

  • The only type casting done in strict mode
  • Integers can be “widened” into floats.
declare(strict_types=1);

function add(float $a, float $b) {
    return $a + $b;
}
var_dump(add(1, 2)); // float(3)

Return Type Declarations




function foo(): array {
    return [];
}

Not Allowed

  • You cannot change the return type of a subclassed method.
class MyClass{
    public function foo(): array {
        return [];
    }
}
class MyOtherClass extends MyClass {
    public function foo(): MyClass {
        return new MyClass();
    }
}






ALLOWED

class MyClass {
    function make(): MyClass {
        return new MyClass();
    }
}
class MyOtherClass extends MyClass {
    function make(): MyOtherClass {
        return new MyOtherClass();
    }
}

Group Use Declarations




Before

namespace MyProj\Command;

use MyProj\Traits\WritelineTrait;
use MyProj\Twitter;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;






After

namespace MyProj\Command;
use MyProj\ {
    Traits\WritelineTrait,
    Twitter
};
use Symfony\Component\Console\ {
    Command\Command,
    Input\InputOption,
    Output\OutputInterface
};

New Features that do not break things




  • Integer Semantics
  • Unicode Codepoint Escape Syntax
  • Array Constants
  • Expectations
The Big 3
PHP NG // Engine Exceptions // Scalar Type Hints
http://img15.deviantart.net/d7ab/i/2011/126/c/e/avengers_big_3_by_bigbmh-d3fomu1.png





Danke schön!

jan@zend.com