TOUT POUR
SE PRÉPARER
À PHP 7.4
Avec la participation de
PaulVerlaine
PROGRAMME
• Incompatibilités
• Nouveautés
• Divers
QUI PARLE?
• Damien Seguy
• CTO @exakat
• Analyse statique PHP
• Maison de retraite à éléphpants
• Record mondial du nombre
d'antennes AFUP visitées
AGENDA
• PHP 7.4.0 RC4
• PHP 7.4.0 RC5 : 31 octobre 2019
• Compilez PHP
• https://github.com/php/php-src
• https://bugs.php.net/
• Compilez votre code : php -l
• php paralell lint
28
nov
2019
INCOMPATIBILITÉS
TERNAIRES IMBRIQUÉS
<?php
1 ? 2 :  3 ?  4 : 5;  // 
(1 ? 2 : 3) ? 4 : 5;  // ok
1 ? 2 : (3 ?  4 : 5); // ok
1 ? 2 ?  3 :  4 : 5;  // ok
?>
EXIT LES SHORTTAG
<?
phpinfo();
?><?php
<?
phpinfo();
?><?php
• Les balises de fin de document changent
PRÉSÉANCE + ET .
<?php
echo 'Nous étions le '. date('d') - 7  . ' mars';
echo 'Nous étions le '. (date('d') - 7) . ' mars';
?>
• Valable aussi pour << >>
• *, **, % sont inchangés
ACCÈSTABLEAUX ACCOLADES
<?php 
$string = 'abc'; 
echo $string[1]; 
echo $string{2}; 
?>
PHP Deprecated: Array and string offset access syntax with curly
braces is deprecated
ACCÈSTABLEAU AUX SCALAIRES
<?php
$integer = 1;
echo $integer[1];
$string = 'abc';
echo $string[1];
?>
PHP Notice: Trying to access array offset on value of type int
PLUS DE REAL
<?php 
$string = '1.2'; 
$real  = (real)  $string;
$float  = (float) $string;
?>
• Uniquement du float
• is_real() et (real)
PHP Deprecated: The (real) cast is deprecated, use (float) instead
ARRAY_KEY_EXISTS()
Deprecated: array_key_exists(): Using array_key_exists() on objects
is deprecated. Use isset() or property_exists() instead
<?php 
$objet = new stdclass;
$objet->p = 1;
var_dump(array_key_exists('p', $objet));
?>
• array_key_exists() a été accéléré
MODERNISATIONS
SÉPARATEUR NUMÉRIQUE
<?php
6.674_083e-11;  // float
22_99_79_24_58;   // decimal
0xCAFE_F00D;    // hexadecimal
0B0101_1111;    // binaire
?>
SÉPARATEUR NUMÉRIQUE
<?php
const _21_ = 22;
echo  _21_;
?>
PROPRIÉTÉSTYPÉES
<?php
class User {
    public int $id;
    public string $name;
public Stdclass $x;
}
?>
PROPRIÉTÉSTYPÉES
<?php 
class User { 
    public Stdclass $x;
    
    function foo() {
        $this->x = new Stdclass;
    }
} 
$a = new User;
$a->foo();
var_dump($a->x);
?>
Fatal error: Uncaught Error: Typed property User::$x must not be
accessed before initialization
OPÉRATEUR … POUR ARRAY
<?php
$parts = ['PHP', 'elephpant', ];
$afup  = ['forum', 'antennes', ...$parts, 'génial'];
// ['PHP', 'elephpant', 'forum', 'antennes', 'génial'
?>
• Ne marche pas avec des hash
FONCTIONS FLÈCHÉES
<?php
$puissance = 2;
$valeurs = [1, 2, 3, 4];
$carres = array_map(
fn($n) => $n ** $puissance, 
$valeurs
);
// $carres = array(1, 4, 9, 16);
?>
FONCTIONS FLÈCHÉES
<?php
$puissance = 2;
$valeurs = [1, 2, 3, 4];
$closure = function (&$n, $k) use ($puissance) {
   $n = $n ** $puissance;
};
array_map($valeurs, $closure);
?>
CONTRAVARIANT
COVARIANT
<?php  
// class/interface b extends a {}
class c1 { 
    function foo(b $arg) : a {} 
} 
class c2 extends c1 { 
    function foo(b $arg) : a {} 
} 
CONTRAVARIANT
COVARIANT
<?php   
// class/interface b extends a {}
class c1 {  
    function foo(a $arg) : b {}  
}  
class c2 extends c1 {  
    function foo(b $arg) : a {}  
} 
Fatal error: Declaration of b::foo(a2 $arg): b1 must be compatible with a::foo(b1
$arg): a2 in test.php on line 10
<?php 
// class/interface b extends a {}
class c1 {
    function foo(b $arg) : a {}
}
class c2 extends c1 {
    function foo(a $arg) : b {}
}
CONTRAVARIANT
COVARIANT
CONTRAVARIANT
COVARIANT
1.Toutes les définitions le même fichier
2.L'autoload est obligatoire
• Moins de vérifications avec le lint
PHP Fatal error: Could not check compatibility between
UserFactory::make(object $arg): User and Factory::make(User $arg):
object, because class User is not available
??=
<?php
$res = shell_exec($cmd) ?? '';
function foo($arg) {
  $arg = $arg ?? '';
  $arg ??= '';
}
foo($arg);
bar($arg ?? '');
?>
ARRAY_MERGE()
<?php
$rows = [[1,2,3], [4,5,6]];
$list = array_merge(...$rows);
$rows = [];
$list = array_merge(...$rows);
?>
RÉFÉRENCES FAIBLES
<?php
$obj = new stdClass;
$weakref = WeakReference::create($obj);
var_dump($weakref->get());
unset($obj);
var_dump($weakref->get());
?>
RÉFÉRENCES FAIBLES
• PHP conserve tous les objets qui sont référencés
en mémoire
• Valable en cas d'utilisation du GC
CachePHP DB
STRIP_TAGS()
<?php
$string = '<a><b><c>';
echo strip_tags($string, '<a><b>');
echo strip_tags($string, ['<a>', '<b>']);
?>
PROC_OPEN()
<?php
proc_open(['php', '-r', 
'echo "Hello Worldn";'], 
$descriptors, $pipes);
shell_exec("php -r " .
escapeshellargs('echo "Hello Worldn";'));
?>
PREG_UNMATCHED_AS_NULL
<?php
preg_match('/(a)(b)?/', 'abc', $r);
/*
Array
(
    [0] => ab
    [1] => a
    [2] => b
)
*/
PREG_UNMATCHED_AS_NULL
<?php
preg_match('/(a)(b)?/', 'amc', $r);
/*
Array
(
    [0] => a
    [1] => a
)
*/
PREG_UNMATCHED_AS_NULL
<?php
preg_match('/(a)(b)?/', 'amc', $r,
PREG_UNMATCHED_AS_NULL);
/*
Array
(
    [0] => a
    [1] => a
    [2] => NULL
)
*/
SERIALISATION NOUVELLE
• __sleep()/__wake()
• Serializable interface
• __serialize() / __unserialize()
• Gère les classes parent
• Plus simple à déserialiser
SERIALISATION NOUVELLE
class B extends A {
    private $prop_b;
    public function __serialize(): array {
        return [
            "prop_b" => $this->prop_b,
            "parent_data" => parent::__serialize(),
        ];
    }
    public function __unserialize(array $data) {
        parent::__unserialize($data["parent_data"]);
        $this->prop_b = $data["prop_b"];
    }
}
DIVERS
PRELOADING
app.php framework.php
Autoload
Output
app.phpwork.php Output
<?php
// create FFI object, loading libc and

// exporting function printf()
$ffi = FFI::cdef(
    "int printf(const char *format, ...);", 

// this is a regular C declaration
    "libc.so.6");
// call C's printf()
$ffi->printf("Hello %s!n", "world");
?>
FOREIGN FUNCTION INTERFACE
• ffi.enable = false
• ext/wddx se retire
• ext/hash s'impose
• PEAR est définitivement mort
• money_format() se retire
• Les classes sans parent ne compile plus parent::
MOINS D'ERREURS
0
125
250
375
500
PHP 5.0 PHP 5.1 PHP 5.2 PHP 5.3 PHP 5.4 PHP 5.5 PHP 5.6 PHP 7.0 PHP 7.1 PHP 7.2 PHP 7.3 PHP 7.4 PHP 8.0
Message d’erreur distinct
PERFORMANCES
• Gain de performances
• 1 à 5 % par rapport à PHP 7.3
• Potentiel de gain avec ext/FFI
• Potentiel de pertes avec les propriétés typées
• Ne pas les utiliser est plus lent!!
AIDE À LA MIGRATION
• Exakat
• Rapports 7.x
• Suggestions
• PHPCompatibility
• PHP CS
BON PHP 7.4!
@exakat

Tout pour se préparer à PHP 7.4