$30 off During Our Annual Pro Sale. View Details »

[php[world] 2014] PHP 5.NEW: The Best Bits

Davey Shafik
November 12, 2014

[php[world] 2014] PHP 5.NEW: The Best Bits

Are you still stuck on PHP 5.2? Looking to migrate from 5.3 to the latest and greatest?

This talk will cover all the best new features and tooling since PHP 5.3, all the way up to PHP 5.6 and beyond.

Namespaces, Closures, Traits, Generators, Variadics/Argument unpacking, and more!

Davey Shafik

November 12, 2014
Tweet

More Decks by Davey Shafik

Other Decks in Programming

Transcript

  1. PHP 5.NEW
    The Best Bits

    View Slide

  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
    • Lead for PHPWomen US
    •@dshafik
    Davey Shafik

    View Slide

  3. $30
    (Includes Taxes & Shipping)

    View Slide

  4. Let’s start a conversation about
    mental health in tech
    prompt.engineyard.com

    View Slide

  5. About These Slides

    View Slide

  6. Proprietary and Confidential
    Two slides per “slide”
    Title Slide (for when I’m talking)
    Details slide (for later)
    Nobody likes it when you can read the slide just as well as the speaker
    can
    I like slides that are useful
    About These Slides

    View Slide

  7. Proprietary and Confidential
    Version Indicator:
    5.X

    View Slide

  8. Proprietary and Confidential
    Version Indicator:
    5.X
    5.X
    +
    Multiple Versions

    View Slide

  9. The Small Stuff

    View Slide

  10. PHP 5.3
    Release Date: June 30th 2009 (5-15% Faster)
    5.3

    View Slide

  11. Proprietary and Confidential
    • Extensions:
    • ereg deprecated
    • SPL always enabled
    • Reflection always enabled
    • NOWDOC
    • Goto
    • stream_context_set_default()
    • Magic Methods:
    • __invoke()
    • __callStatic()
    • __call() now called on protected/private method access
    • Performance Increase!
    PHP 5.3
    5.3

    View Slide

  12. PHP 5.4
    Release Date: March 1st 2012 (10-15% Faster)
    5.4

    View Slide

  13. Proprietary and Confidential
    • SessionHandlerInterface added, used with
    session_set_save_handler()
    • PHP_BINARY constant gives the path to the... PHP binary
    • Notice now shown on array-to-string conversions
    • UTF-8 by default (instead of iso-8859-1)
    • Array callbacks — $foo = [$obj, ‘method’]; $foo =
    [“Class”, “method”]; then: $foo();
    • Callable typehint, accepts function names, array callbacks, closures,
    classes with __invoke() magic method
    • Better Memory Usage and Performance
    • (even better than PHP 5.3)
    PHP 5.4
    5.4

    View Slide

  14. PHP 5.5
    Release Date: June 20th 2013
    5.5

    View Slide

  15. Proprietary and Confidential
    • PCRE /e Modifier deprecated
    • ext/mysql now officially deprecated
    • boolval() to complement intval(), floatval()/doubleval(),
    strval(). Same as (bool) $var;
    • JsonSerializable interface
    • Fully-qualified Class name constant: ClassName::CLASS
    • empty() now supports any valid expression
    • set_(error|exception)_handler() to NULL to return to default
    behavior
    PHP 5.5
    5.5

    View Slide

  16. PHP 5.6
    Release Date: August 28th 2014
    5.6

    View Slide

  17. Proprietary and Confidential
    • T_POW: ** Exponent operator, raise left operand to the power of right
    • Constant Scalar Expressions
    • __debugInfo() magic method — intercept var_dump()
    • GMP operator overloading (engine level only
    !)
    PHP 5.6
    5.6

    View Slide

  18. Namespaces
    Better Code Organization
    5.3
    5.6
    +

    View Slide

  19. Proprietary and Confidential
    • Avoid Naming Collisions
    • Alias Long Names
    • Must be defined at the top
    • Relative Namespaces are Supported
    • Import/Alias with "use" keyword
    • Can namespace classes, functions, and constants (using const)
    Namespaces
    namespace Zend\Http\Client\Adapter;
    class Socket implements HttpAdapter, StreamInterface
    {
    }
    ?>
    5.3

    View Slide

  20. Proprietary and Confidential
    Namespaces
    namespace Zend;
    use Zend\Http\Client\Adapter\Socket as HttpClient;
    $client = new Http\Client\Adapter\Socket;
    $client = new HttpClient;
    $client = new Zend\Http\Client\Adapter\Socket;
    ?>
    5.3

    View Slide

  21. PSR-0
    A new standard
    5.3

    View Slide

  22. Proprietary and Confidential
    http://xkcd.com/927/
    5.3

    View Slide

  23. Proprietary and Confidential
    • Remove leading namespace separator
    • Replace namespace separator with directory separator
    • Replace underscores with directory separator
    • Add .php to the end
    PSR-0
    5.3

    View Slide

  24. Proprietary and Confidential
    namespace Zend\Http\Client\Adapter;
    class Socket implements HttpAdapter, StreamInterface
    {
    }
    ?>
    PSR-0
    5.3

    View Slide

  25. Proprietary and Confidential
    namespace Zend\Http\Client\Adapter;
    class Socket implements HttpAdapter, StreamInterface
    {
    }
    ?>
    PSR-0
    5.3

    View Slide

  26. Proprietary and Confidential
    namespace Zend\Http\Client\Adapter;
    class Socket implements HttpAdapter, StreamInterface
    {
    }
    ?>
    PSR-0
    5.3

    View Slide

  27. Proprietary and Confidential
    namespace Zend\Http\Client\Adapter;
    class Socket implements HttpAdapter, StreamInterface
    {
    }
    ?>
    PSR-0
    5.3

    View Slide

  28. Proprietary and Confidential
    Composer
    getcomposer.org
    5.3

    View Slide

  29. Proprietary and Confidential
    Composer
    composer.json:
    {
    "require": {
    "monolog/monolog": "1.2.*",
    "phpunit/phpunit": "3.*",
    "zend/zendframework": ">=2.0, < 3.0",
    "zend/zendframework": "~2.0"
    }
    }
    5.3

    View Slide

  30. Proprietary and Confidential
    Install dependencies (from composer.lock)
    $ composer install
    Update dependencies & write composer.lock
    $ composer update
    Composer
    5.3

    View Slide

  31. Proprietary and Confidential
    require 'vendor/autoload.php';
    use Zend\Http\Client\Adapter\Socket as HttpClient;
    $client = new HttpClient; 

    // Automagically (lazy) loaded
    Optimize the Autoloader with a classmap:
    $ composer install --optimize-autoloader
    $ composer update --optimize-autoloader
    Autoloading
    5.3

    View Slide

  32. Import Namespaced Functions & Constants
    5.6

    View Slide

  33. Proprietary and Confidential
    • Prior to PHP 5.6:
    • Outside of the namespace, function names/constants had to be fully
    qualified
    • You could alias the namespace to shorten it (ugh!)
    • Add two new keyword sequences:
    • use function \foo\bar\function
    • use const \foo\bar\BAZ
    • Use commas to import multiples
    Import Namespaced Functions & Constants
    5.6

    View Slide

  34. Proprietary and Confidential
    Import Namespaced Functions & Constants
    namespace foo\bar {
    const HELLO_WORLD = "Hello World";
    function strlen($str) {
    return \strlen($str);
    }
    }
    namespace {
    use function foo\bar\strlen;
    use function foo\bar\non_existent; // Doesn't exist!
    use const foo\bar\HELLO_WORLD;
    var_dump(strlen(HELLO_WORLD)); // not ambiguous
    var_dump(non_existent()); // Does not fall-through
    // to global scope: fatal error
    }
    5.6

    View Slide

  35. Proprietary and Confidential
    Great for DSLs!
    Import Namespaced Functions & Constants
    use function html\div, html\p, html\em;
    $html = div(p('Some', em('Text')));
    5.6

    View Slide

  36. Closures
    5.3
    5.4
    +

    View Slide

  37. Proprietary and Confidential
    Closures
    $a = array(3, 2, 5, 6, 1);
    usort($a, function ($a, $b) {
    if ($a == $b) {
    return 0;
    }
    return ($a < $b) ? -1 : 1;
    });
    ?>
    5.3

    View Slide

  38. Proprietary and Confidential
    • Explicitly passed in via the use construct
    Inheriting Scope
    $who = "World";
    $sayHello = function() use ($who) {
    echo "Hello $who";
    };
    $sayHello();
    5.3

    View Slide

  39. Proprietary and Confidential
    • $this now accessible inside closures (based on creation location)
    • Array callbacks for variable function calls
    • Change $this and/or scope with Closure::bind() and 

    Closure->bindTo()
    $this in closures
    5.4

    View Slide

  40. Proprietary and Confidential
    class foo {
    public function getClosure() {
    return function() { 

    return $this;
    }
    }
    }
    class bar {
    public function __construct() {
    $foo = new foo();
    $func = $foo->getClosure();
    $obj = $func(); 

    // PHP 5.3: $obj == null
    // PHP 5.4: $obj == foo, not bar
    }
    }
    5.4

    View Slide

  41. Rebinding $this
    Or: How to break the object model!
    5.4

    View Slide

  42. Proprietary and Confidential
    • Doesn’t change the original closure — creates a duplicate
    • $this can be any object
    • $this and scope are separate — $this can be a different class to the
    access scope.
    Rebinding $this
    5.4

    View Slide

  43. Proprietary and Confidential
    Rebinding $this
    class foo {
    public function getClosure() {
    return function() {
    echo $this->hello;
    $this->world();
    };
    }
    }
    class bar {
    public $hello = "Hello ";
    private function world() { echo "World"; }
    }
    $foo = new Foo();
    $closure = $foo->getClosure();
    $bar = new Bar();
    $newClosure = $closure->bindTo($bar);
    $newClosure();
    5.4

    View Slide

  44. Proprietary and Confidential
    Hello
    Fatal error: Call to private method
    bar::world() from context 'foo'
    Output
    5.4

    View Slide

  45. Proprietary and Confidential
    Rebinding $this
    class foo {
    public function getClosure() {
    return function() {
    echo $this->hello;
    $this->world();
    };
    }
    }
    class bar {
    public $hello = "Hello ";
    private function world() { echo "World"; }
    }
    $foo = new Foo();
    $closure = $foo->getClosure();

    $bar = new Bar();
    $newClosure = $closure->bindTo($bar);
    $newClosure = $closure->bindTo($bar, $bar);
    $newClosure(); // Hello World
    5.4

    View Slide

  46. Dereferencing
    5.4
    5.5
    +

    View Slide

  47. Proprietary and Confidential
    Array Dereferencing
    function returnArray() {
    return ['a' => 'b', 'c' => 'd'];
    }
    $foo = returnArray()['a']; // b
    5.4
    5.5
    Literal Dereferencing
    ["one", "two", "three"][0]; // "one"
    "foo"[0]; // f

    View Slide

  48. Traits
    AKA Horizontal Re-use
    5.4

    View Slide

  49. Proprietary and Confidential
    • Compiler-level copy and paste (almost literally!)
    • New Keywords: trait, use, as and insteadof
    • Can use multiple traits
    – as and insteadof resolve conflicts
    • Can define methods, abstract methods, and properties
    • Can be namespaced, identified just like classes/functions/constants
    Traits
    5.4

    View Slide

  50. Proprietary and Confidential
    namespace Ds\Util;
    trait SecureDebugInfo {
    public function __debugInfo() {
    $info = (array) $this;
    foreach ($info as $key => $value) {
    // Hide elements starting with '_'
    if ($key[0] == '_') {
    unset($info[$key]);
    }
    }
    }
    }
    Defining a Trait
    5.4

    View Slide

  51. Proprietary and Confidential
    • Uses the “use” keyword
    • Use multiple traits like namespaces, separate use calls, or comma-
    separated.
    Using a Trait
    namespace Ds;
    class MyClass {
    use Util\SecureDebugInfo;
    }
    5.4

    View Slide

  52. Proprietary and Confidential
    trait One {
    public function one() { }
    }
    trait Two {
    public function two() { }
    }
    trait Three {
    use One, Two; // Trait three now comprises of 

    // all three traits.
    public function Three() { }
    }
    Inheriting In Traits
    5.4

    View Slide

  53. Proprietary and Confidential
    class Numbers {
    use One; // Adds One->one()
    public function two() { }
    public function three() { }
    }
    class MoreNumbers extends Numbers {
    use Two; // Two->two() overrides Numbers->two()
    public function one() { } // Overrides Numbers->one()
    } (Trait One->one)
    class EvenMoreNumbers extends MoreNumbers {
    use Three; // Three->one() overrides MoreNumbers->one()
    // Three->two() overrides MoreNumbers->two() 

    // (Trait Two->two)
    // Three->three() overrides inherited 

    Numbers->three()
    public function three() { } // Overrides Three->three()
    }
    Inheritance & Traits 5.4

    View Slide

  54. Proprietary and Confidential
    namespace Ds\Util;
    trait SecureDebugInfo {
    public function __debugInfo()
    {
    return $this->getData();
    }
    abstract public function getData();
    }
    Trait Requirements
    5.4

    View Slide

  55. Proprietary and Confidential
    Fatal error: Trait method has not been
    applied, because there are collisions with other
    trait methods on
    class MyClass {
    use Ds\Util\SecureDebugInfo, 

    My\Framework\DebugHelper {
    Ds\Util\SecureDebugInfo::__debugInfo
    insteadof My\Framework\DebugHelper;
    }
    }
    Conflict Resolution
    5.4

    View Slide

  56. Proprietary and Confidential
    class MyClass {
    use Ds\Util\SecureDebugInfo,
    My\Framework\DebugHelper {
    Ds\Util\SecureDebugInfo::__debugInfo
    insteadof My\Framework\DebugHelper;
    My\Framework\DebugHelper::__debugInfo
    as debugHelperInfo;
    }
    }
    Aliases
    5.4

    View Slide

  57. Proprietary and Confidential
    class MyClass {
    use MyTrait {
    MyTrait::myMethod as protected;
    MyTrait::myOtherMethod as private AliasName;
    }
    }
    Changing Visibility
    5.4

    View Slide

  58. Proprietary and Confidential
    class Numbers {
    use One, Two;
    }
    var_dump(class_uses('Numbers'));
    Output:
    array(2) {
    ["One"]=>
    string(3) "One"
    ["Two"]=>
    string(3) "Two"
    }
    Using Array Dereferencing:
    if (class_uses('MyClass')['SomeTrait']) {
    // MyClass uses the SomeTrait
    }
    Detecting Traits
    5.4

    View Slide

  59. Proprietary and Confidential
    trait sayHello {
    public function hello() { echo "Hello "; }
    }
    trait sayWorld {
    public function world() { echo "World"; }
    }
    class sayHelloWorld {
    use sayHello, sayWorld;
    }
    $say = new sayHelloWorld();
    $say->hello(); // Hello
    $say->world(); // World
    Traits

    View Slide

  60. Proprietary and Confidential
    trait getHello {
    public function hello() { return "Hello"; }
    }
    trait getWorld {
    public function world() { return "World"; }
    }
    trait sayHelloWorld {
    use getHello, getWorld;
    public function helloWorld() {
    echo $this->hello(), " ", $this->world();
    }
    }
    class Greeting {
    use sayHelloWorld;
    }
    (new Greeting)->helloWorld(); // Hello World
    Inheritance/Scope

    View Slide

  61. Proprietary and Confidential
    class say {
    public function sayHello() {
    echo 'Hello ';
    }
    }
    trait sayWorld {
    public function sayHello() {
    parent::sayHello(); // parent is unknown
    echo 'World';
    }
    }
    class HelloWorld extends say {
    use sayWorld; // parent == say
    }
    class HiMum extends HelloWorld {
    public function sayHello() {
    parent::sayHello(); // parent == HelloWorld == sayWorld
    echo ", Hi mum!", PHP_EOL;
    }
    }
    (new HelloWorld)->sayHello(); echo PHP_EOL; // Hello World
    (new HiMum)->sayHello(); // Hello World, Hi mum!
    Precedence

    View Slide

  62. Proprietary and Confidential
    trait sayHello {
    public function hello() { echo "Hello "; }
    }
    trait sayWorld {
    private function world() { echo "World"; }
    }
    class sayHelloWorld {
    use sayHello, sayWorld {
    world as public;
    }
    }
    $say = new sayHelloWorld();
    $say->hello(); // Hello
    $say->world(); // World
    Method Visibility

    View Slide

  63. Proprietary and Confidential
    trait sayHello {
    public function hello() { echo "Hello "; }
    }
    trait sayWorld {
    private function world() { echo "World"; }
    }
    class sayHelloWorld {
    use sayHello, sayWorld {
    hello as greeting;
    world as public planet;
    }
    }
    $say = new sayHelloWorld();
    $say->greeting(); // Hello
    $say->planet(); // World
    Method Aliases

    View Slide

  64. Proprietary and Confidential
    trait hello_en {
    public function greet() { echo "Hello "; }
    }
    trait mother_en_US {
    public function mother() { echo "Mom"; }
    }
    trait mother_en_UK {
    public function mother() { echo "Mum"; }
    }
    class HiMother {
    use hello_en, mother_en_US, mother_en_UK;
    public function sayHi($locale = 'UK') {
    $this->greet();
    ($locale != 'US') ? $this->mother() : $this->mom();
    }
    }
    (new HiMother)->sayHi('UK');
    (new HiMother)->sayHi('US');
    Fatal error: Trait method mother has not been applied, because there are
    collisions with other trait methods on HiMother on line 28
    Conflicts

    View Slide

  65. Proprietary and Confidential
    trait hello_en {
    public function greet() { echo "Hello "; }
    }
    trait mother_en_US {
    public function mother() { echo "Mom"; }
    }
    trait mother_en_UK {
    public function mother() { echo "Mum"; }
    }
    class HiMother {
    use hello_en, mother_en_US, mother_en_UK {
    mother_en_UK::mother insteadof mother_en_US;
    mother_en_US::mother as mom;
    }
    public function sayHi($locale = 'UK') {
    $this->greet();
    ($locale != 'US') ? $this->mother() : $this->mom();
    }
    }
    (new HiMother)->sayHi('UK'); // Hello Mum
    (new HiMother)->sayHi('US'); // Hello Mom
    Conflict Resolution

    View Slide

  66. Short Echo Tags
    5.4

    View Slide

  67. Proprietary and Confidential
    No longer depends on short_open_tags
    Short Echo Tags
    ="Now I Will Always Work!";?>
    5.4

    View Slide

  68. Binary Numbers
    5.4

    View Slide

  69. Proprietary and Confidential
    Binary Numbers
    $var = 0b01; // Binary (base 2)
    In Addition To:
    $var = 1234; // Integer
    $var = -123; // Signed Integer (+/-)
    $var = 1.23; // Float
    $var = 0123; // Octal (base 8)
    $var = 0x1A; // Hexadecimal (base 16)
    5.4

    View Slide

  70. Short Array Syntax
    5.4

    View Slide

  71. Proprietary and Confidential
    Short Array Syntax
    // Old
    $array = array(1, 2, 3);
    // New
    $array = [1, 2, 3];
    // Old
    $a = array('a' => 'b', 'c' => 'd');

    // New
    $a = ['a' => 'b', 'c' => 'd'];
    5.4

    View Slide

  72. Dynamic Method Calls
    5.4

    View Slide

  73. Proprietary and Confidential
    Dynamic Method Calls
    // Variable static methods
    $var = "staticMethod";
    ClassName::{$var}();
    // Instantiation Time Access
    (new ClassName)->instanceMethod();


    // UGLY.
    $var = "instanceMethod";
    (new ClassName)->{$var}();
    5.4

    View Slide

  74. list() support in foreach
    5.5

    View Slide

  75. Proprietary and Confidential
    • Allows assignment of nested array values (1st level) to
    multiple variables, within the foreach declaration
    list() support in foreach
    $result = [
    [
    'name' => 'Davey Shafik',
    'email' => '[email protected]',
    ],
    [
    'name' => 'Helgi Þormar Þorbjörnsson',
    'email' => '[email protected]',
    ]
    ];
    foreach ($result as list($name, $email)) {
    echo $name, ': ', $email . PHP_EOL;
    }
    5.5

    View Slide

  76. Constant Scalar Expressions
    5.6

    View Slide

  77. Proprietary and Confidential
    • Use expressions when defining:
    • global constants with const keyword
    • class constants with the const keyword
    • class properties
    • static variables
    • function arguments
    Constant Scalar Expressions
    5.6

    View Slide

  78. Proprietary and Confidential
    • 123 - Integers
    • 123.456 - Floats
    • “foo” - Strings
    • __LINE__ - Line magic constant
    • __FILE__ - File magic constant
    • __DIR__ - Directory magic constant
    • __TRAIT__ - Trait magic constant
    • __METHOD__ - Method magic constant
    • __FUNCTION__ - Function magic constant
    • __NAMESPACE__ - Namespace magic constant
    • <<• <<<'NOWDOC' - NOWDOC string syntax
    • SOME_RANDOM_CONSTANT - Constants
    Expression Suppport
    5.6

    View Slide

  79. Proprietary and Confidential
    Global constants with const keyword
    const FOO = 1 + 1;
    const BAR = 1 << 1;
    const GREETING = "HELLO";
    const BAZ = GREETING." WORLD!"
    5.6

    View Slide

  80. Proprietary and Confidential
    Class constants with the const keyword
    class Foo {
    const FOO = 1 + 1;
    const BAR = 1 << 1;
    const GREETING = "HELLO";
    const BAZ = self::GREETING." WORLD!"
    }
    5.6

    View Slide

  81. Proprietary and Confidential
    Class Properties
    class Foo {
    const BAZ = 10;
    }
    class Bar {
    public $foo = 1 + 1;
    public $bar = [
    1 + 1,
    1 << 2,
    Foo::BAZ => "foo "."bar"
    ];
    public $baseDir = __DIR__ . "/base";
    }
    5.6

    View Slide

  82. Proprietary and Confidential
    Static Variables
    const BAR = 0x10;
    function foo() {
    static $a = 1 + 1;
    static $b = [1 << 2];
    static $c = 0x01 | BAR;
    }
    5.6

    View Slide

  83. Proprietary and Confidential
    Function Arguments
    const BAR = 1;
    function f($a = 1 + 1, $b = 2 << 3, $c = BAR?10:100)
    {
    }
    5.6

    View Slide

  84. __debugInfo()
    5.6

    View Slide

  85. Proprietary and Confidential
    Magic method to control the output of var_dump()
    __debugInfo()
    class File {
    // "Resource(stream)" isn't all that useful
    private $fp;
    // But all the stream meta data is
    public function __debugInfo() {
    return $this->fp ? stream_get_meta_data($fp) : [];
    }
    public function open($filename, $mode = 'r'){
    $this->fp = fopen($filename, $mode);
    }
    }
    5.6

    View Slide

  86. Proprietary and Confidential
    __debugInfo() (Cont.)
    $f = new File;
    var_dump($f); // object(File)#1 { }
    $f->open('http://php.net');
    var_dump($f);
    /*
    object(File)#1 {
    ["wrapper_type"]=>
    string(4) "http"
    ["stream_type"]=>
    string(10) "tcp_socket"
    etc...
    */
    5.6

    View Slide

  87. “finally” keyword
    5.5

    View Slide

  88. Proprietary and Confidential
    • Code within a finally block is always run after either of the
    try, or catch blocks.
    • Remember: Catch is optional
    “finally” keyword
    try {
    // Try something
    } catch (\Exception $exception) {
    // Handle exception
    } finally {
    // Whatever happened, do this
    }
    5.5

    View Slide

  89. Fully Qualified Classname Constant
    5.5

    View Slide

  90. Proprietary and Confidential
    • Easy access to the fully qualified class name via a simple constant.
    Allows for easy dynamic creation of class (think: Reflection, Unit
    Testing)
    Fully Qualified Classname Constant
    namespace App {
    class Config { }
    $className = "Config";
    new $className; // Fatal error: Class 'Config' not found
    // Instead:
    $className = "App\Config";
    new $className; // Works
    // Added in 5.5:
    $className = Config::class; // = App\Config
    new $className;
    }
    5.5

    View Slide

  91. Simple Password Hashing
    5.5

    View Slide

  92. Proprietary and Confidential
    • Makes password hashing super easy
    • Purpose: to make sure everyone uses safe password
    storage
    • Uses the excellent bcrypt (currently)
    • Salting is automatic, but can be supplied
    • The hash itself identifies the algorithm, salt and options
    options when passed to password_verify()
    •You may pass an array with salt and cost as third
    argument to password_hash()
    Simple Password Hashing
    5.5

    View Slide

  93. Proprietary and Confidential
    Simple Password Hashing (cont.)
    $options = [
    'cost' => 20,
    'salt' => 'bcryptuses22characters'
    ];
    $hash = password_hash("testing", PASSWORD_DEFAULT, $options);
    $hash = password_hash("testing", PASSWORD_DEFAULT);
    if (password_verify("testing", $hash)) {
    // valid
    }
    Specify Options:
    5.5

    View Slide

  94. Proprietary and Confidential
    • Also provides two helper functions:
    –password_needs_rehash() will determine if the hash uses the
    current algorithm, cost and salt, returning true if it doesn’t match.
    –password_get_info() returns an array providing information about
    a hash such as algorithm, cost and salt.
    Simple Password Hashing (cont.)
    5.5

    View Slide

  95. More on password security
    5.5

    View Slide

  96. Proprietary and Confidential
    • A strong salt makes a dictionary attack much more difficult
    • A high cost means it takes a long time (say, 1/10th second)
    to generate a single password, making brute force attacks
    too slow to be effective
    • The cost is what makes SHA-1 and MD5 poor options
    because they are designed to be fast, this is the enemy of
    security.
    • Additionally, MD5 suffers from too many easy collisions (e.g.
    two different strings that create the same hash)
    More on password security
    Goal: Make both dictionary and brute force attacks difficult.
    5.5

    View Slide

  97. Proprietary and Confidential
    Hashing Rates
    Algorithm
    Hashes/
    second
    MD5 SHA-1 SHA-512 bcrypt
    MD5
    180 Billion/
    second
    65% Faster
    99.9997%
    Faster
    99.9999996%
    Faster
    SHA-1
    63 Billion/
    second
    185% Slower
    99.9994%
    Faster
    99.999887%
    Faster
    SHA-512
    364,000/
    second
    49.5M%
    Slower
    17.3M%
    Slower
    80.49%
    Faster
    bcrypt
    71,000/
    second
    253.5M%
    Slower
    88.7M%
    Slower
    412% Slower
    Data Source: http://passwords12.at.ifi.uio.no/Jeremi_Gosney_Password_Cracking_HPC_Passwords12.pdf
    5.5

    View Slide

  98. Generators
    5.5

    View Slide

  99. Proprietary and Confidential
    • Introduces new yield keyword - execution is handed back
    to the iterating mechanism (e.g. foreach) and then continues
    from, the yield
    • Functions and methods are automatically return generators
    when yield is found within them
    • Generators are just simple ways to implement iterators;
    without having to duplicate a bunch of boilerplate code
    • Technically implemented using the Generator class, similar
    to the magic Closure class.
    Generators
    5.5

    View Slide

  100. Proprietary and Confidential
    Anatomy of Generator Flow
    function helloGenerator($who) {
    // First iteration starts here
    $greeting = ["Hello", "Hi", "Hola", "Bonjour"][rand(0, 3)];
    yield $greeting; // Control passed back to foreach
    // Next iteration starts here
    yield " "; // Control passed back to foreach
    // Third iteration starts here
    yield ucfirst($who) . "!\n"; // Control passed back to foreach
    }
    $generator = helloGenerator("world"); // No code is executed yet
    foreach ($generator as $value) {
    echo $value;
    }
    Output: $RandomGreeting World!\n
    5.5

    View Slide

  101. Proprietary and Confidential
    Anatomy of Generator Flow (Cont.)
    function MyGenerator() {
    // First iteration starts here
    for ($i = 0; $i < 5; $i++) {
    yield $i; // Control passed back to foreach
    // Second iteration starts here
    // The for iteration completes, and goes to the next loop
    }
    }
    0: 0
    1: 5
    2: 10
    3: 15
    4: 20
    Output
    5.5

    View Slide

  102. Proprietary and Confidential
    Anatomy of Generator Flow (Cont.)
    function gen() {
    echo "One";
    yield "Two";
    echo "Three";
    yield "Four";
    echo "Five";
    }
    $generator = gen();
    $generator->rewind();
    if ($generator->valid()) {
    echo $generator->current();
    }
    $generator->next();
    5.5

    View Slide

  103. Proprietary and Confidential
    Anatomy of Generator Flow (Cont.)
    function gen() {
    echo "One";
    yield "Two";
    echo "Three";
    yield "Four";
    echo "Five";
    }
    $generator = gen();
    $generator->rewind();
    if ($generator->valid()) {
    echo $generator->current();
    }
    $generator->next();
    5.5

    View Slide

  104. Proprietary and Confidential
    Anatomy of Generator Flow (Cont.)
    function gen() {
    echo "One";
    yield "Two";
    echo "Three";
    yield "Four";
    echo "Five";
    }
    $generator = gen();
    $generator->rewind();
    if ($generator->valid()) {
    echo $generator->current();
    }
    $generator->next();
    5.5

    View Slide

  105. Proprietary and Confidential
    Anatomy of Generator Flow (Cont.)
    function gen() {
    echo "One";
    yield "Two";
    echo "Three";
    yield "Four";
    echo "Five";
    }
    $generator = gen();
    $generator->rewind();
    if ($generator->valid()) {
    echo $generator->current();
    }
    $generator->next();
    5.5

    View Slide

  106. Proprietary and Confidential
    Anatomy of Generator Flow (Cont.)
    function gen() {
    echo "One";
    yield "Two";
    echo "Three";
    yield "Four";
    echo "Five";
    }
    $generator = gen();
    $generator->rewind();
    if ($generator->valid()) {
    echo $generator->current();
    }
    $generator->next();
    5.5

    View Slide

  107. Proprietary and Confidential
    Anatomy of Generator Flow (Cont.)
    function gen() {
    echo "One";
    yield "Two";
    echo "Three";
    yield "Four";
    echo "Five";
    }
    $generator = gen();
    $generator->rewind();
    if ($generator->valid()) {
    echo $generator->current();
    }
    $generator->next();
    5.5

    View Slide

  108. Proprietary and Confidential
    Anatomy of Generator Flow (Cont.)
    function gen() {
    echo "One";
    yield "Two";
    echo "Three";
    yield "Four";
    echo "Five";
    }
    $generator = gen();
    $generator->rewind();
    if ($generator->valid()) {
    echo $generator->current();
    }
    $generator->next();
    5.5

    View Slide

  109. Proprietary and Confidential
    Anatomy of Generator Flow (Cont.)
    function gen() {
    echo "One";
    yield "Two";
    echo "Three";
    yield "Four";
    echo "Five";
    }
    $generator = gen();
    $generator->rewind();
    if ($generator->valid()) {
    echo $generator->current();
    }
    $generator->next();
    5.5

    View Slide

  110. Proprietary and Confidential
    Anatomy of Generator Flow (Cont.)
    function gen() {
    echo "One";
    yield "Two";
    echo "Three";
    yield "Four";
    echo "Five";
    }
    $generator = gen();
    $generator->rewind();
    if ($generator->valid()) {
    echo $generator->current();
    }
    $generator->next();
    5.5

    View Slide

  111. Proprietary and Confidential
    Anatomy of Generator Flow (Cont.)
    function gen() {
    echo "One";
    yield "Two";
    echo "Three";
    yield "Four";
    echo "Five";
    }
    $generator = gen();
    $generator->rewind();
    if ($generator->valid()) {
    echo $generator->current();
    }
    $generator->next();
    5.5

    View Slide

  112. Proprietary and Confidential
    Anatomy of Generator Flow (Cont.)
    function gen() {
    echo "One";
    yield "Two";
    echo "Three";
    yield "Four";
    echo "Five";
    }
    $generator = gen();
    $generator->rewind();
    if ($generator->valid()) {
    echo $generator->current();
    }
    $generator->next();
    5.5

    View Slide

  113. Proprietary and Confidential
    • A return; (note: a return with a value is a parse error)
    • An exception is thrown (and not caught within the generator)
    • There are no more yields
    Anatomy of Generator Flow (Cont.)
    Generators will return true for valid() until:
    5.5

    View Slide

  114. Sending Data into a Generator
    5.5

    View Slide

  115. Proprietary and Confidential
    • You can send any data into a generator
    • It is used as an expression, rather than a statement
    • This also advances the generator
    • You can send and receive at the “same time”
    Sending data into a Generator
    function logger($fileName) {
    $fileHandle = fopen($fileName, 'a');
    while (true) {
    fwrite($fileHandle, yield . PHP_EOL);
    }
    }
    $logger = logger(__DIR__ . '/log');
    $logger->send('Foo');
    $logger->send('Bar');
    5.5

    View Slide

  116. Confession Time
    5.5

    View Slide

  117. Proprietary and Confidential
    • My first implementation for the next slide didn’t work how I
    expected!
    • Neither did the 2nd, 3rd or 4th...
    • In fact, I thought I found a bug
    • Then I created a test case, and things started to make
    sense
    • I still don’t think there’s any reasonable use-case for this
    functionality!
    Confession Time
    5.5

    View Slide

  118. Proprietary and Confidential
    Test Case
    function gen() {
    $i = 0;
    while (true) {
    file_put_contents("./log",
    myDate() .' '.
    (yield $i++) . ' ' .
    PHP_EOL
    , FILE_APPEND);
    }
    }
    function myDate() {
    return date("Y-m-d H:i:s");
    }
    $gen = gen();
    var_dump($gen->send("First Call")); // 1
    sleep(3);
    var_dump($gen->send("Second Call")); // 2
    Log File
    2013-02-04 03:39:51 First Call
    2013-02-04 03:39:51 Second Call
    5.5

    View Slide

  119. Proprietary and Confidential
    Iteration 1
    5.5

    View Slide

  120. Proprietary and Confidential
    Iteration 1
    5.5

    View Slide

  121. Proprietary and Confidential
    Iteration 1
    5.5

    View Slide

  122. Proprietary and Confidential
    Iteration 1
    5.5

    View Slide

  123. Proprietary and Confidential
    Iteration 1
    5.5

    View Slide

  124. Proprietary and Confidential
    Iteration 1
    5.5

    View Slide

  125. Proprietary and Confidential
    Iteration 1
    5.5

    View Slide

  126. Proprietary and Confidential
    Iteration 1
    5.5

    View Slide

  127. Proprietary and Confidential
    Iteration 1
    5.5

    View Slide

  128. Proprietary and Confidential
    Iteration 1
    5.5

    View Slide

  129. Proprietary and Confidential
    Iteration 1
    5.5

    View Slide

  130. Proprietary and Confidential
    Iteration 1
    5.5

    View Slide

  131. Proprietary and Confidential
    Iteration 1
    5.5

    View Slide

  132. Proprietary and Confidential
    Iteration 1
    5.5

    View Slide

  133. Proprietary and Confidential
    Iteration 2 5.5

    View Slide

  134. Proprietary and Confidential
    Iteration 2 5.5

    View Slide

  135. Proprietary and Confidential
    Iteration 2 5.5

    View Slide

  136. Proprietary and Confidential
    Iteration 2 5.5

    View Slide

  137. Proprietary and Confidential
    Iteration 2 5.5

    View Slide

  138. Proprietary and Confidential
    Iteration 2 5.5

    View Slide

  139. Proprietary and Confidential
    Iteration 2 5.5

    View Slide

  140. Proprietary and Confidential
    Iteration 2 5.5

    View Slide

  141. Proprietary and Confidential
    Iteration 2 5.5

    View Slide

  142. Proprietary and Confidential
    Iteration 2 5.5

    View Slide

  143. Proprietary and Confidential
    Iteration 2 5.5

    View Slide

  144. Sending Exceptions into Generators
    5.5

    View Slide

  145. Proprietary and Confidential
    • Sends an exception into the Generator
    • Throws the exception at the yield
    • The actual yielded value isn’t returned
    Sending Exceptions into Generators
    5.5

    View Slide

  146. Proprietary and Confidential
    Sending Exceptions into Generators
    function gen() {
    echo "Foo\n";
    try {
    while (true) { yield "bat"; }
    } catch (Exception $e) {
    echo "Exception: {$e->getMessage()}\n";
    }
    echo "Bar\n";
    }
    $gen = gen();
    var_dump($gen->current());
    // echos "Foo" and dumps string (3) "bat"
    $gen->throw(new Exception('Test'));
    // echos "Exception: Test" and "Bar"
    var_dump($gen->valid());
    // dumps bool(false)

    5.5

    View Slide

  147. Variadic Functions
    5.6

    View Slide

  148. Proprietary and Confidential
    Variadic Syntax
    … $variable
    5.6

    View Slide

  149. Proprietary and Confidential
    • Variadic means to accept a variable number of arguments
    • Previously you needed to use func_num_args()/func_get_args()
    • Which includes defined arguments also!
    • New syntax: "… $variable" (triple dot)
    • Array with just the variable arguments
    • Self-documenting code
    • Supports by-reference
    • Allows type hints
    • Must be the last argument!
    Variadic Functions
    5.6

    View Slide

  150. Proprietary and Confidential
    Variadic Functions
    function fn($reqParam, $optParam = null, ...$params) {
    var_dump($reqParam, $optParam, $params);
    }
    fn(1); // 1, null, []
    fn(1, 2); // 1, 2, []
    fn(1, 2, 3); // 1, 2, [3]
    fn(1, 2, 3, 4); // 1, 2, [3, 4]
    fn(1, 2, 3, 4, 5); // 1, 2, [3, 4, 5]
    5.6

    View Slide

  151. Proprietary and Confidential
    Variadic Functions — References
    5.6
    class MySQL implements DB {
    public function prepare($query, &...$params) {
    $stmt = $this->pdo->prepare($query);
    foreach ($params as $i => &$param) {
    $stmt->bindParam($i + 1, $param);
    }
    return $stmt;
    }
    // ...
    }
    $stmt = $db->prepare(

    'INSERT INTO users
    (name, email, age) 

    VALUES (?, ?, ?)', $name, $email, $age);

    foreach ($usersToInsert as list($name, $email, $age)) {
    $stmt->execute();
    }

    View Slide

  152. Proprietary and Confidential
    Variadic Functions — Type hints
    function hooks($name, Callable ... $callbacks) {
    foreach ($callbacks as $callback) {
    $callback();
    }
    }
    5.6

    View Slide

  153. Argument Unpack (AKA: SPLAT)
    5.6

    View Slide

  154. Proprietary and Confidential
    Splat Syntax
    … $variable
    5.6

    View Slide

  155. Proprietary and Confidential
    Splat Syntax
    fn(… $variable);
    5.6

    View Slide

  156. Proprietary and Confidential
    • The opposite of variadics, unpack an array (or similar) as arguments
    • No more call_user_func_array() (which is “slow”)
    • Valid for any argument list (including new foo(… $var))
    • Must be at the end of the argument list
    • Use it multiple times!
    Splat
    5.6

    View Slide

  157. Proprietary and Confidential
    Splat
    function test(...$args) { var_dump($args); }
    test(1, 2, 3); // [1, 2, 3]
    test(...[1, 2, 3]); // [1, 2, 3]
    test(...new ArrayIterator([1, 2, 3])); // [1, 2, 3]
    5.6

    View Slide

  158. Proprietary and Confidential
    Splat
    $args1 = [1, 2, 3];
    $args2 = [4, 5, 6];
    test(...$args1, ...$args2); // [1, 2, 3, 4, 5, 6]
    test(1, 2, 3, ...$args2); // [1, 2, 3, 4, 5, 6]

    test(...$args1, 4, 5, 6); // [1, 2, 3, 4, 5, 6]
    5.6

    View Slide

  159. Proprietary and Confidential
    Feedback & Questions: 

    Feedback: https://joind.in/

    Twitter: @dshafik
    Email: [email protected]
    Slides: http://daveyshafik.com/slides
    11900

    View Slide