Meetup PHP 7 avancé

PHP 7.0 et PHP 7.1

Paris, 25 octobre 2016

Appuyez sur [s] pour ouvrir les notes présentateur dans une nouvelle fenêtre.

Utilisez la touche [ESPACE]
pour passer au slide suivant.

On en est où ?

  • PHP 5.6
    • Dernière version 5.x
    • Publiée le 28 août 2014
  • PHP 7.0
    • Publiée le 3 décembre 2015
  • PHP 7.1
    • RC4 il y a quelques jours
    • Publication : fin 2016 ?

Versions supportées

Supported Versions

php.net/supported-versions.php

PHP 7.0

Les nouveautés

Avant de commencer...

  • Besoin marketing
  • 10 ans de PHP 5.x
  • Performances : limite du moteur PHP 5 atteintes
  • Possibilité de casser des choses
  • Des nouveautés !

Null Coalesce Operator


$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
	                    

$username = $_GET['user'] ?? 'nobody';
	                    

$model = Model::get($id) ?? $default_model;
	                    

Unicode Codepoint Escape Syntax


$ php -r 'echo "I \u{2665} PHP!\n";'
I ♥ PHP!
	                    

$ php -r 'echo "\u{1F408} \u{1F431} \u{1F638} \u{1F639} \u{1F63A} \u{1F63B} \u{1F63C} \u{1F63D} \u{1F63E} \u{1F63F} \u{1F640} - so cute!!!\n";'
🐈 🐱 😸 😹 😺 😻 😼 😽 😾 😿 🙀 - so cute!!!
	                    

Type hints scalaires


function add(int $a, int $b) {
    return $a + $b;
}
	                    

var_dump( add(10, 20) );
var_dump( add('10', '20') );
	                    

int(30)
int(30)
	                    

Type hints scalaires


try {
    var_dump( add(10, 'abc') );
}
catch (TypeError $e) {
    var_dump( $e->getMessage() );
}
	                    

string(148) "Argument 2 passed to add()
    must be of the type integer, string given,
    called in .../test-01.php on line 12"
	                    

Types de retour


function add(int $a, int $b) : int {
    return $a + $b;
}
	                    

Types de retour


function get_config() : array {
    return 42;
}
get_config();
	                    

Fatal error: Uncaught TypeError:
    Return value of get_config() must be
    of the type array, integer returned
	                    

Typage strict


declare(strict_types=1);

function add(int $a, int $b) {
    return $a + $b;
}

add(10, '20');
	                    

Fatal error: Uncaught TypeError:
    Argument 2 passed to add()
    must be of the type integer, string given
	                    

Souple / Strict ?

  • Paramètres : au choix de l'appelant
    • Sait si il manipule des types souples ou stricts
  • Retour : au choix de l'appelé
    • Sait si la fonction qu'il a écrite utilise des types souples ou stricts

Souple / Strict ?

  • Les données sont des types indiqués.
  • Détermine si des conversions sont ou non permises.

Combined Comparison (Spaceship) Operator


function order_func($a, $b) {
    return $a <=> $b;
}
	                    

function order_func($a, $b) {
    return [$a->x, $a->y, $a->foo]
        <=> [$b->x, $b->y, $b->foo];
}
	                    

Group use declarations


use Mon\Espace\De\Nom\ClasseAa;
use Mon\Espace\De\Nom\ClasseBb;
use Mon\Espace\De\Nom\ClasseCc;
use Mon\Espace\De\Nom\Enfant\AutreClasse as ClassDd;
	                    

use Mon\Espace\De\Nom\ {
    ClasseAa, ClasseBb, ClasseCc,
    Enfant\AutreClasse as ClassDd
};
	                    

Group use declarations


use function Mon\Nom\fonc01;
use const Mon\Nom\CONST01;
use Mon\Nom\Class01;
	                    

use Mon\Nom\ {
    function fonc01,
    const CONST01,
    Class01
};
	                    

Erreurs → exceptions

  • Une partie des erreurs Fatales
  • internes à / levées par PHP
  • sont transformées en Error
  • qui peuvent être catchées

Erreurs → exceptions


$obj = null;
try {
    // Ooops !
    $obj->methode();
}
catch (Error $e) {
    var_dump($e>getMessage());
}
	                    

string(43) "Call to a member function methode() on null"
	                    

Erreurs → exceptions

Hiérarchie d'erreurs / exceptions


interface Throwable

    Exception implements Throwable
        // Toutes les exceptions usuelles

    Error implements Throwable
        AssertionError extends Error
        ParseError extends Error
        TypeError extends Error
	                    

Classes anonymes


$obj = new class ("Monde") {
    protected $qui;

    public function __construct($qui) {
        $this->qui = $qui;
    }

    public function hello() {
        printf("Hello, %s !\n", $this->qui);
    }
};

var_dump($obj);
$obj->hello();
	                    

Generators et return


function plop() {
    yield 100;
    yield 200;
    return 42;
}

foreach (($generator = plop()) as $val) {
    var_dump($val);
}

var_dump( $generator->getReturn() );
	                    

int(100)
int(200)
int(42)
	                    

Generator Delegation


function test() {
    yield from [10, 20, 30];
}

foreach (test() as $val) {
    var_dump($val);
}
	                    

int(10)
int(20)
int(30)
	                    

Generator Delegation


function sub_generator_1() {
    yield 10;
    yield 20;
}
function sub_generator_2() {
    yield from [ 'aa', 'bb', ];
}

function delegating_generator() {
    yield from sub_generator_1();
    yield from sub_generator_2();
}
                    

foreach (delegating_generator() as $val) {
    // Travail avec $val
}
	                    

Bonus

  • Migration PHP 5.6 → 7.0 assez facile
  • Performances ++

PHP 7.1

Les nouveautés

Cycle de releases

Depuis PHP 5.4

  • 1 version mineure tous les ans
  • 2 ans de support
  • + 1 an de support de sécurité

PHP 7.0 est sortie il y a un an ;-)

Class Constant Visibility


class MaClasse {
    public const MA_PUBLIQUE = 42;
    private const MA_PRIVEE = 1234;
    public function test() {
        var_dump( self::MA_PRIVEE );
    }
}
						

var_dump( MaClasse::MA_PUBLIQUE ); // int(42)
(new MaClasse())->test(); // int(1234)
						

// Error: Cannot access private const MaClasse::MA_PRIVEE
var_dump( MaClasse::MA_PRIVEE );
	                    

Allow specifying keys in list()


$array = [
    'glop' => "Hello",
    'plop' => 123456,
    'who' => "World",
];
	                    

list (
    'glop' => $a,
    'who' => $b
) = $array;
	                    

var_dump($a, $b);
// string(5) "Hello"
// string(5) "World"
	                    

[] for array destructuring assignment


[$a, $b] = [10, 20];
var_dump($a, $b);
// int(10)
// int(20)
	                    

['glop' => $glop, 'plop' => $plop] = [
    'plop' => 42,
    'glop' => "Hello",
];
var_dump($plop, $glop);
// int(42)
// string(5) "Hello"
	                    

Generalize support of negative string offsets


$str = "Pascal";
var_dump($str[2]);  // string(1) "s"
var_dump($str[-2]); // string(1) "a"
	                    

Generalize support of negative string offsets


$str = "Pas.al";
$str[-3] = 'c';
var_dump($str);  // string(6) "Pascal"
	                    

Generalize support of negative string offsets


var_dump( strpos("Pascal", "c", -5) ); // int(3)
	                    

Catching Multiple Types


class Plop extends Exception {}
class Blah extends Exception {}
class Another extends Exception {}
	                    

try {
    switch (mt_rand(0, 2)) {
        case 0: throw new Plop();
        case 1: throw new Blah();
        case 2: throw new Another();
    }
} catch (Plop | Blah $e) {
    printf("1er catch : %s\n", get_class($e));
} catch (Another $e) {
    printf("2nd catch : %s\n", get_class($e));
}
	                    

Throw Error in Extensions

La majorité des erreurs fatales levées par des extensions intégrées à PHP sont converties en exceptions.

Nullable Types

PHP 7.0


function fonc01(int $a) {
    var_dump($a);
}
	                    

fonc01(100); // int(100)

fonc01(null); // TypeError: Argument 1 passed to
              // fonc01() must be of the type
              // integer, null given
	                    

Nullable Types

PHP 7.1


function fonc01(?int $a) {
    var_dump($a);
}
	                    

fonc01(100); // int(100)
fonc01(null); // NULL
	                    

fonc01();
// Error: Too few arguments to function fonc01(), 0 passed
	                    

Nullable Types


function fonc02(?int $a, ?int $b) : ?int {
    if ($a === null || $b === null) {
        return null;
    }
    return $a + $b;
}
	                    

var_dump( fonc02(10, 20) ); // int(30)
var_dump( fonc02(10, null) ); // NULL
	                    

Void Return Type


function fonc01() {
    printf("%s\n", __FUNCTION__);
}
	                    

function fonc02() : void {
    printf("%s\n", __FUNCTION__);
}
	                    

function function03() : void {
    printf("%s\n", __FUNCTION__);

    // Fatal error: A void function must not return a value
    return 'plop';
}
	                    

Iterable


function fonc01(iterable $data) {
    foreach ($data as $key => $val) {
        // ...
    }
}
	                    

fonc01( [10, 20, 30] );
fonc01( new SplFixedArray(5) );
fonc01( mon_generateur() );
	                    

Closure::fromCallable()


function ma_fonction() {
    var_dump(__FUNCTION__);
}
	                    

$closure = Closure::fromCallable('ma_fonction');
$closure();  // string(11) "ma_fonction"
	                    

$closure = Closure::fromCallable('plop');
// TypeError: Failed to create closure from callable:
// function 'plop' not found or invalid function name
	                    

Bref, PHP 7.1

  • Bientôt !
  • Encore temps de tester une RC ;-)
  • Nouvelles fonctionnalités
  • Quelques (petits) bc-breaks

Et après ?

PHP 7.2

WIP ;-)

PHP 8.0

WIP ;-)

Pascal MARTIN

blog.pascal-martin.fr
contact@pascal-martin.fr
@pascal_martin

TEA, The Ebook Alternative

php7avance.fr — @php7avance