Appuyez sur [s] pour ouvrir les notes présentateur dans une nouvelle fenêtre.
                        Utilisez la touche [ESPACE]
pour passer au slide suivant.
                    
 
                        
                     
						
						
					 
                        Source : w3techs.com
 
                        Source : w3techs.com
Depuis PHP 5.4
Support de sécurité allongé pour PHP 5.6
$ tree php-108
php-108
├── common.c
├── common.h
├── config.h
├── error.c
...
├── README
├── subvar.c
├── version.h
├── wm.c
└── wm.h
0 directories, 18 files
                        
<?
    msqlsethost("localhost");
    $name = "bob";
    $result = msql($database,"select * from table where firstname='$name'");
    $num = msql_numrows($result);
    echo "$num records found!<p>";
    $i=0;
    while($i<$num);
        echo msql_result($result,$i,"fullname");
        echo "<br>";
        echo msql_result($result,$i,"address");
        echo "<br>";
        $i++;
    endwhile;
>
                        
<?
    msqlsethost("localhost");
    $name = "bob";
    $result = msql($database,"select * from table where firstname='$name'");
    $num = msql_numrows($result);
    echo "$num records found!<p>";
    $i=0;
    while($i<$num);
        echo msql_result($result,$i,"fullname");
        echo "<br>";
        echo msql_result($result,$i,"address");
        echo "<br>";
        $i++;
    endwhile;
>
                        Migration PHP 4 → 5 difficile
Novembre 2005
Novembre 2006
DateTimeJuin 2009
?:, goto, mysqlnd, Garbage Collector, Phar, Intl, Fileinfo, Sqlite3Un tournant dans l'utilisation de PHP
 
						
					Mars 2012
register_globals, magic_quotes, safe_modeJuin 2013
finally, ::class, API mots de passeGenerators
Août 2014
use pour fonctions et constantes**, surcharge d'opérateurs (classes internes), phpdbgPHP 6 and MySQL 5 for Dynamic Web Sites: Visual QuickPro Guide
 
                        
                    PHP 6 Fast and Easy Web Development
 
                        
                    Professional PHP6 (Wrox Programmer to Programmer)
 
                        
                    PHP 6/MySQL Programming for the Absolute Beginner
 
                        
                    PHP6 and MySQL Bible
 
                        
                     
                        
                    
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
	                    
$username = $_GET['user'] ?? 'nobody';
	                    
$model = Model::get($id) ?? $default_model;
	                    
$ 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!!!
	                    
function add(int $a, int $b) {
    return $a + $b;
}
	                    
var_dump( add(10, 20) );
var_dump( add('10', '20') );
	                    
int(30)
int(30)
	                    
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"
	                    
function add(int $a, int $b) : int {
    return $a + $b;
}
	                    
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
	                    
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
	                    
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];
}
	                    
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
};
	                    
use function Mon\Nom\fonc01;
use const Mon\Nom\CONST01;
use Mon\Nom\Class01;
	                    
use Mon\Nom\ {
    function fonc01,
    const CONST01,
    Class01
};
	                    Error
$obj = null;
try {
    // Ooops !
    $obj->methode();
}
catch (Error $e) {
    var_dump($e>getMessage());
}
	                    
string(43) "Call to a member function methode() on null"
	                    
$php = <<<'PHP'
$a = 10        // -- Parse error ! -- //
printf("\$a = %d\n", $a);
PHP;
try {
    eval($php);
}
catch (ParseError $e) {
    var_dump($e->getMessage());
}
	                    
string(44) "syntax error, unexpected 'printf' (T_STRING)"
	                    
echo "Fichier 1 - avant\n";
try {
    // Fichier avec une erreur de syntaxe
    include __DIR__ . '/test-06-2.php';
}
catch (Error $e) {
    echo "Error catchée : ";
    var_dump($e->getMessage());
}
echo "Fichier 1 - après\n";
	                    
Fichier 1 - avant
Error catchée : string(42) "syntax error, unexpected '$b' (T_VARIABLE)"
Fichier 1 - après
	                    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
	                    
$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();
	                    
$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();
	                    
object(class@anonymous)#1 (1) {
  ["qui":protected]=>
  string(5) "Monde"
}
Hello, Monde !
	                    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)
	                    
function test() {
    yield from [10, 20, 30];
}
foreach (test() as $val) {
    var_dump($val);
}
	                    
int(10)
int(20)
int(30)
	                    
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
}
	                    
$data = unserialize($serialized, [
    "allowed_classes" => false
]);
                    
$data = unserialize($serialized, [
    "allowed_classes" => [
        MaClasse::class,
        'MonAutreClasse',
    ]
]);
                        
var_dump( random_int(10, 100) );
var_dump( bin2hex(random_bytes(12)) );
                        
int(23)
string(24) "903c636403869d3c3ab3310e"
                        jsondJSON_PRESERVE_ZERO_FRACTION pour json_encode()
var_dump( json_encode(42.0) );
var_dump( json_encode(42.0, JSON_PRESERVE_ZERO_FRACTION) );
                        
string(2) "42"
string(4) "42.0"
                         
                        
                     
                        
                     
                        
                        
                     
                        
                        
                     
                        
                     
                        
                     
                        
                     
                        
                     
                        
                     
                        
                     
                        
                    Pour en savoir plus sur les changements internes :
PHP 7 – What changed internally? - Nikita Popov - Forum PHP 2015
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 );
	                    list()
$array = [
    'glop' => "Hello",
    'plop' => 123456,
    'who' => "World",
];
	                    
list (
    'glop' => $a,
    'who' => $b
) = $array;
	                    
var_dump($a, $b);
// string(5) "Hello"
// string(5) "World"
	                    
[$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"
	                    
$str = "Pascal";
var_dump($str[2]);  // string(1) "s"
var_dump($str[-2]); // string(1) "a"
	                    
$str = "Pas.al";
$str[-3] = 'c';
var_dump($str);  // string(6) "Pascal"
	                    
var_dump( strpos("Pascal", "c", -5) ); // int(3)
	                    
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));
}
	                    La majorité des erreurs fatales levées par des extensions intégrées à PHP sont converties en exceptions.
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
	                    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
	                    
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
	                    
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';
}
	                    
function fonc01(iterable $data) {
    foreach ($data as $key => $val) {
        // ...
    }
}
	                    
fonc01( [10, 20, 30] );
fonc01( new SplFixedArray(5) );
fonc01( mon_generateur() );
	                    
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
	                    Assez peu de bc-breaks
Mais quand même.
Usage interdit en tant que :
intfloatboolstringtrue et falsenullOn sait jamais ^^
resourceobjectscalarmixednumericSupprimés !
<% et <%= ... %>asp_tags<script language="php"> ... </script>
                            <? et <?= sont conservés !
                        
Suppression d'extensions
ext/ereg → PCREext/mysql → mysqliEnfin !
Suppression d'extensions
ext/mssqlext/sybase_ctext/imap et ext/mcrypt ont été conservées, mais sont basées sur des bibliothèques non maintenues !
Suppression des fonctionnalités obsolètes
new by referenceset_magic_quotes_runtime() et magic_quotes_runtime()dl() on fpm-fcgi$this contextSuppression des fonctionnalités obsolètes
mbstring et iconv# dans les fichiers .ini$is_dst de mktime() et gmmktime()xsl.security_prefsSuppression des fonctionnalités obsolètes
/e de preg_replace()setlocale()Suppression de SAPIs
sapi/aolserversapi/apachesapi/apache_hookssapi/apache2filtersapi/caudiumsapi/continuitysapi/isapiSuppression de SAPIs
sapi/miltersapi/phttpdsapi/pi3websapi/roxensapi/thttpdsapi/tuxsapi/webjamesswitch + >1 default
switch (10) {
    default:
        var_dump("premier default");
        break;
    default:
        var_dump("second default");
        break;
}
                        
Fatal error: Switch statements may only contain one default clause
                        E_DEPRECATEDE_STRICT transformées en E_DEPRECATED ou E_NOTICE ou E_WARNING"OxAB"
function plop() {
    return [
        'a' => 'aaa',    // Nom d'une fonction
        'b' => 'bbb',
        'c' => 'ccc',
    ];
}
function aaa() { var_dump(__FUNCTION__); }    // La fonction
function bbb() { var_dump(__FUNCTION__); }
function ccc() { var_dump(__FUNCTION__); }
$fonction = 'plop';
$fonction()['a']();
                        
class MaClasse {
    public $propriete;
    public function __construct($val) {
        $this->propriete = $val;
    }
}
$a = new MaClasse(42);
$b = new MaClasse(123);
var_dump( [ $a, $b ][0]->propriete );
                        
class MaClasse {
    public function maMethode() {
        var_dump(__METHOD__);
    }
}
$obj = new MaClasse();
[ $obj, 'maMethode' ]();
                        
class MaClasse {
    public static function maMethode() {
        var_dump(__METHOD__);
    }
}
$methode = 'maMethode';
'MaClasse'::$methode();
                        Appel d'une fonction anonyme
function ma_fonction() {
    var_dump(__FUNCTION__);
}
( function () {
    return 'ma_fonction'();
})();
                        Écriture désormais invalide :
global $$foo->bar;
                        À remplacer par :
global ${$foo->bar};
                        Changements
// écriture          // PHP 5               // PHP 7
$$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']()
                        Casse Magento 1.x ;-)
Oui...
var_dump('10 apples' + '5 oranges');
// Notice: A non well formed numeric value encountered in .../01-warn-invalid-string-arithmetic.php on line 7
// Notice: A non well formed numeric value encountered in .../01-warn-invalid-string-arithmetic.php on line 7
// int(15)
                        
var_dump(10 + "plop");
// Warning: A non-numeric value encountered in .../01-warn-invalid-string-arithmetic.php on line 12
// int(10)
                        
function my_function($a, $b) { ... }
my_function(10);
                        
PHP <= 7.0
    Warning: Missing argument 2 for my_function(),
        called in ... and defined in ...
    int(10)
    NULL
                        
PHP >= 7.1
    Fatal error: Uncaught Error: Too few arguments to function my_function(),
        1 passed in ... and exactly 2 expected in ...
                        Ne spécifier que les paramètres utiles
htmlspecialchars($string, double_encode => false);
                        Ou juste s'y retrouver
strpos(hasytack => "foobar", needle => "bar");
                        Bah non.
while ($cond) {
    // loop body
}
or {
    // did not enter while loop
}
                        Non plus.
Pas la façon de faire de PHP.
pthreadsExactement comme pour n'importe quelle autre montée de version !
Travail tout juste commencé, mais déjà une bonne dizaine de RFCs acceptées ;-)
session_gc(), session_create_id()E_WARNING for invalid container array-accessget_class() disallow null parameter
$var = false;
$var[1][2][3][4][5];
// This will throw a single E_WARNING, as accessing ($a[1])[2]
// is attempting to access a IS_VAR chain that is NULL.
                        
$var = array(123);
$var[0][1];
// This will throw an E_WARNING, as accessing $a[0] is valid
// [1] is accessing an integer as an array.
                        png2wbmp() and jpeg2wbmp()HashContext as ObjectINTL_IDNA_VARIANT_2003Pour l'instant, à peine évoqué comme cible d'évolutions ou refontes.
                            Surtout cible de quelques suppressions et bc-breaks, anticipés dès PHP 7.1 et 7.2 par j'ajout de E_DEPRECATED.
                        
mb_ereg_replace() eval optionpng2wbmp() and jpeg2wbmp()Les six-huit prochains mois vont être intéressants !
L'appel à conférenciers et conférencières est encore ouvert ;-)
 
                        
                     
                        
                     
                        
                    Pascal MARTIN
	                            blog.pascal-martin.fr
	                            
contact@pascal-martin.fr
	                            
@pascal_martin
	                        
 
                    Meetup « PHP 7.x », Marseille/Aix & Montpellier, 21-22 fév. 2017 — Pascal MARTIN