Présentation PHP 7
En bref :
Aperçu des nouvelles fonctionnalités
2017-02-13
## Agenda
- Timeline
- Passer à PHP 7 ?
- Checklist de migration
- Pourquoi PDO ?
- Nouveautés
- PHP 7.1
- Tester une migration à PHP 7
- Symfony
- Des questions ?
# Timeline
Timeline
*Source : https://fr.wikipedia.org/wiki/PHP*
Voici un petit historique des versions de PHP depuis sa naissance.
1.0
Appelé officiellement "Personal Home Page Tools (PHP Tools)", outils pour page personnelle. C'est la première apparition du nom "PHP"
2.0
Appelé officiellement "PHP/FI 2.0", c'est la première version qui pourrait effectivement être qualifiée de PHP
comme étant une langue autonome avec de nombreuses fonctionnalités.
3.0
Passage d'une personne à une équipe de développeurs. Zeev Suraski et Andi Gutmans réécrivent la base de cette version
4.0
Ajout d'un système d'analyse syntaxique plus avancé appelé le Zend Engine. Ce moteur procède en deux étapes d'analyse puis d'exécution.
Introduit les superglobals.
Introduit le CLI, en addition au CGI.
5.0
Zend Engine II avec un nouveau modèle objet.
5.1
Naissance de PDO
Amélioration de performances par l'introduction de variables de compilation dans un moteur PHP repensé
5.3
Beaucoup de choses avec :
Support des espaces de noms ; Late Static Bindings (résolution statique à la volée) ; étiquettes de saut (goto limité) ;
fermetures (closures) ; Native PHP archives (phar) ; raccourci pour l'opérateur ternaire (?:) ; fonctions anonymes ; nombreuses corrections de bug ; Introduit PHP-FPM
5.4
Support des traits ; syntaxe courte des tableaux introduite ; accès aux index de tableaux en sortie de fonctions ; les fermetures supportent $this ;
accès aux attributs d'un objet dès l'instanciation ; ajout syntaxe Class::{expr}() ; ajout format de nombres binaires ;
suivi des envois de fichiers via l'extension de session ; serveur web embarqué en CLI dédié au développement ;
Timeline
*Source : http://php.net/supported-versions.php*
Passer à PHP 7 ?
Passer à PHP 7 ?
PHP 5
est maintenant âgé de 13 ans
+ PHP 7
est assez mature
Comme on l'a vu sur la timeline il était temps de passer à une nouvelle version majeure après 13 ans de service pour PHP 5!
De plus, PHP 7 est assez mature pour se permettre cette transition!
Passer à PHP 7 ?
**De meilleures performances grâce à PHPNG**
(PHP Next Generation)
=
**à Facebook HHVM**
(HipHop Virtual Machine)
Plus d'infos sur le bench : http://talks.php.net/oz15#/drupalbench
Cette nouvelle version est basée sur PHPNG (pour PHP Next-Generation).
Une initiative qui a été lancée par Zend en réponse à la technologie HHVM de Facebook,
qui avait pour but de proposer une version de PHP qui se voulait plus performante.
Selon Zend, la mise à jour des applications vers PHP 7 pourrait engendrer un surcroît de performance de 25% à 70%.
L'éditeur a publié quelques indicateurs qu'il a résumé en une infographie publiée en mai 2015 .
Ces comparatifs montrent que WordPress (en version 4.1) serait deux fois plus rapide avec PHP 7 qu'avec PHP 5.6, et Drupal (7) 70% plus rapide.
A travers son benchmark, le projet PHP met aussi en avant un niveau d'optimisation qui se veut être au même niveau que celui de HHVM, voire légèrement au dessus.
Pour info la machine virtuelle HHVM permet optimiser le développement, le débogage et l'exécution de code PHP.
Le langage Hack créé aussi par Facebook et proche du PHP est utilisé sur la quasi-totalité du site de Facebook
et s'exécute au sein d'une machine virtuelle HHVM.
Passer à PHP 7 ?
*Source : https://www.zend.com*
Passer à PHP 7 ?
*Source : https://www.zend.com*
Ce graphique est à prendre avec des pincettes, notamment pour Ruby qui depuis sa version 2.3 a des performances équivalentes avec PHP 7.
Quoique la 7.1 qui est sortie il y a quelques semaines est encore plus prometteuse.
Passer à PHP 7 ?
*Source : https://twitter.com/andygrunwald/status/735515546033262592*
Sur ce graphique on a une représentation plus concrète du passage à PHP 7 pour le site de comparaison d'hôtels Trivago.
Seule la configuration de FPM a été modifiée. Les admins n'ont pas eu besoin de toucher au serveur web ou au php.ini
Passer à PHP 7 ?
Quelques cas d'étude
* [Badoo qui a préservé 1 million de dollars](https://techblog.badoo.com/blog/2016/03/14/how-badoo-saved-one-million-dollars-switching-to-php7/) en passant à PHP 7
* [Tumblr qui a réduit sa latence et charge CPU de moitié](https://engineering.tumblr.com/post/152998126990/php-7-at-tumblr)
* [Dailymotion qui gère deux fois plus de traffic](http://engineering.dailymotion.com/php-7-deployment-at-dailymotion/) avec la même infrastructure en passant à PHP 7.
D'autres acteurs du net...
PHP 6 ?
Prise en charge de l'Unicode au coeur du langage.
Non publié, le projet a été abandonné.
Plus d'infos : https://wiki.php.net/rfc/php6
L'accumulation du retard et des problèmes a conduit en mars 2010 à l'abandon du projet PHP 6 : les morceaux rassemblés jusque-là
furent alors intégrés dans la version 5.4.
Checklist de migration
Checklist de migration
Suppression des fonctionnalités dépréciées
https://wiki.php.net/rfc/remove_deprecated_functionality_in_php7
mysql_* < MySQLi < PDO
ereg* < pcre
Extension mysql supprimée et donc les fonctions mysql_* associées.
En résumé vous devrez passer à PDO!
L'extension mssql a également été supprimée.
ereg* sont à remplacer par les PCRE (Perl Compatible Regular Expression)
Checklist de migration
Directives INI supprimées
✘ always_populate_raw_post_data
✘ asp_tags
always_populate_raw_post_data : si défini à TRUE, PHP va toujours peupler la variable $HTTP_RAW_POST_DATA des données brutes POST
asp_tags : Active l'utilisation des balises ASP (<% %>) tout en conservant les balises PHP (). Cela inclut l'utilisation des balises courtes comme <%= $valeur %>
Checklist de migration
## Constructeurs PHP 4 dépréciés
````php
class Filter {
public function filter() { ... }
}
new Filter();
````
https://wiki.php.net/rfc/remove_php4_constructors
Checklist de migration
## Mots clés réservés supplémentaires
`bool`, `int`, `float`, `string`, `resource`, ...
````php
class resource {
public function __construct() { ... }
}
new resource();
````
````text
Fatal error: "resource" cannot be used as a classname.
````
https://wiki.php.net/rfc/reserve_more_types_in_php_7
https://wiki.php.net/rfc/reserve_even_more_types_in_php_7
Certains types sont devenus des mots clés réservés pour les noms de classes, traits et interfaces.
Par exemple ceci vous retournera une erreur fatale.
Checklist de migration
## "default" unique pour switch
````php
switch($expr) {
default:
neverExecuted();
break;
default:
executed();
}
````
````text
Fatal error: Switch statements may only contain one default clause.
````
## Pourquoi PDO ?
Pourquoi PDO ?
Flexibilité des vendors
PostgreSQL
SQLite
MySQL
Oracle
ODBC
MS SQLServer & Azure
Firebird
Informix
IBM DB2
Sybase
Cubrid
4D
Tout d'abord un point fort de PDO est la disponibilité des drivers pour plusieurs SGBD maintenus par la communauté PHP.
Pourquoi PDO ?
Facilité d'installation
##### Debian (via Dotdeb repository)
````text
sudo apt-get install php7.0-mysql
````
##### CentOS / RHEL (via Remi repository)
````text
sudo yum install php-pdo php-mysql
````
##### Neard : activé par défaut
Pourquoi PDO ?
Méthode de connexion unifiée et standard
````php
// MySQL
$dbh = new PDO("mysql:host=$host;dbname=$dbname, $user, $pass");
// MSSQL
$dbh = new PDO("mssql:host=$host;dbname=$dbname, $user, $pass");
// Sybase
$dbh = new PDO("sybase:host=$host;dbname=$dbname, $user, $pass");
// SQLite
$dbh = new PDO("sqlite:my/database/path/database.db");
````
Pourquoi PDO ?
Prepared statements pour se protéger des injections
````php
// No placeholders
$sth = $dbh->prepare("INSERT INTO users (name, email) VALUES ($name, $email)");
// Unnamed placeholders
$sth = $dbh->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$sth->bindParam(1, $name);
$sth->bindParam(2, $email);
// Named placeholders
$sth = $dbh->prepare("INSERT INTO users (name, email) VALUES (:name, :email)");
$sth->bindParam(':name', $name);
$sth->bindParam(':email', $email);
// Execute
$sth->execute();
````
Evitez la première, elle est là pour exemple de comparaison.
Pour les deux autres solutions ça dépendra de comment vous affectez les données àvos statements.
Pourquoi PDO ?
##### Pour plus d'infos je vous invite à lire cet article :
https://code.tutsplus.com/tutorials/why-you-should-be-using-phps-pdo-for-database-access--net-12059
# Nouveautés
Nouveautés
Types scalaires pour les paramètres
##### Types scalaires
`bool`, `int`, `float`, `string`.
##### Typehint
````php
function formatDateInFrench(DateTime $date) {
return $date->format('d/m/Y');
}
````
Les types scalaires sont les types les plus simples en PHP, ce sont sont avec lesquels vous avez appris à utiliser le langage : bool, int, float, string.
Ce sont des types extremement courants dans vos développement quotidiens, je pense que l'on peut se passer de beaucoup plus d'explications.
Le typehint permet d'imposer à une fonction d'accepter uniquement des données d'un certain type. Introduit avec PHP 5.0, cela vous permet d'être certain
que ce que vous recevez dans votre fonction est effectivement une données du type souhaité.
(NEXT)
Vous n'avez pas besoin de alors de vous demander si $date est du type DateTime, vous avez la garantie qu'il l'est.
Si un objet d'un autre type est passé en paramètre, une Fatal Error sera déclenchée.
Nouveautés
Null coalesce operator
````php
// Before
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
````
````php
// After
$username = $_GET['user'] ?? 'nobody';
````
PHP étant un langage orienté vers le web, le fait de traiter des variables (tester leurs existences et fournir une valeur par défaut) est très fréquent.
Jusqu'à là il n'existait pas de méthode plus courte que celle-ci.
NEXT
Ce nouveau opérateur fournir une syntaxe plus courte et plus facilement compréhensible.
Nouveautés
Spaceship operator
````php
// Before
function foo($a ,$b) {
if ($a == $b) {
return 0;
} elseif ($a > $b) {
return -1;
} elseif ($b > $a) {
return 1;
}
}
````
````php
// After
function foo($a ,$b) {
return $a <=> $b;
}
````
C'est un nouveau opérateur qui retourne 0 si les deux opérandes sont égaux, 1 si celui de gauche est plus grand et -1 si celui de droite est plus grand.
Son utilité est fréquente, particulièrement dans les algorithmes de tri.
Avant nous avions : NEXT
Nouveautés
Type de retour
````php
// After
function isValidStatusCode(int $statusCode): bool {
return isset($this->statuses[$statusCode]);
}
````
On peut maintenant spécifier le type de retour d'une fonction ou d'une méthode. Pour cela il suffit d'ajouter deux points et le type que la fonction/méthode retourne.
Si le mode stricte n'est pas activé, quand une variable du mauvais type est retournée elle est convertie vers le bon type. Sinon un Fatal Error est déclenché.
Nouveautés
Typage strict
````php
declare(strict_types=1);
function add(int $a, int $b) {
return $a + $b;
}
add(10, '20');
````
````text
Fatal error: Uncaught TypeError:
Argument 2 passed to add()
must be of the type integer, string given
````
Si l'approche souple du typage ne vous satisfait pas ou que vous êtes certains des types de données
manipulés par votre code, vous pouvez activer un mode de typage strict, pour le fichier courant.
Ici, puisque '20' n'est pas un entier et que nous sommes en mode de typage strict, une TypeError sera levée :
Pour la distinction entre typage souple et typage strict :
- Pour les paramètres, c'est au choix de l'appelant : c'est lui qui sait s'il manipule des données en types souples ou stricts.
- Pour la valeur de retour, c'est au choix de l'appelé, qui sait si la fonction qu'il a écrite utilise des types souples ou stricts.
Dans tous les cas, à l'intérieur de la fonction, les données sont des types indiqués : le paramétrage souple ou strict détermine uniquement si les conversions sont permises.
Nouveautés
Classes anonymes
````php
// Before
class Logger {
public function log($msg) {
echo $msg;
}
}
$util->setLogger(new Logger());
````
````php
// After
$util->setLogger(new class {
public function log($msg) {
echo $msg;
}
});
````
Le support pour les classes anonymes a été rajouté en PHP 7. Les classes anonymes sont utiles lorsque de simples objets uniques ont besoin d'être créés.
On peut leur passer des arguments via le constructeur, elles peuvent étendre d'autres classes, implémenter des interfaces ou utiliser des traits comme avec avec une classe normale.
Nouveautés
Améliorations sur la gestion des erreurs
* Erreurs fatales internes → exceptions
* Hiérarchie d'erreurs / exceptions
Nouveautés
Erreurs fatales internes → exceptions
````php
$obj = null;
try {
// Ooops !
$obj->methode();
} catch (Error $e) {
var_dump($e>getMessage());
}
````
````text
string(43) "Call to a member function methode() on null"
````
Avec PHP 7.0, une partie des erreurs Fatales et internes à / levées par PHP sont transformées en Error, qui peuvent être catchées. Par exemple :
Cette portion de code qui aurait entrainé en PHP 5 une Fatal Error mettant fin à l'exécution du script,
mène désormais à la sortie suivante, où nous sommes passés dans le bloc catch :
J'insiste : cette modification, qui va fortement aider ceux qui font tourner des programmes PHP pendant longtemps, ne s'applique pour l'instant qu'à certaines erreurs fatales, et uniquement levées depuis le moteur de PHP.
Nouveautés
Hiérarchie d'erreurs / exceptions
````text
interface Throwable
Exception implements Throwable
// Toutes les exceptions usuelles
Error implements Throwable
AssertionError extends Error
ParseError extends Error
TypeError extends Error
````
Pour accompagner ce changement, la hiérarchie des classes d'exceptions a été revue, avec l'introduction d'une interface Throwable commune à tous les types d'exceptions.
Les exceptions usuelles continuent d'hériter de Exception, alors que les erreurs héritent quant à elles de Error, qui est une classe-soeur de Exception
De la sorte, le code qui attrapait une Exception ne se retrouve pas subitement, à partir de PHP 7.0, à également attraper les Error,
assurant que le comportement de votre code ne changera pas en passant de PHP 5 à PHP 7.
Nouveautés
Plus d'infos : http://php.net/manual/fr/migration70.new-features.php
Bien sûr, je n'ai pas listé ici toutes les nouveautés de PHP 7.0 et me suis limité à celles qui avaient le plus attiré mon attention.
# PHP 7.1
PHP 7.1
##### Visibilité des constantes de classe
````php
class Foo {
public const PUB_BAR = 42;
private const PRIV_BAR = 1234;
public function bar() {
var_dump(self::PRIV_BAR);
}
}
````
Les constantes de classes supportent désormais les visibilités public, protected et private.
Les constantes sans visibilité seront attribuées comme publiques.
Les interfaces, elles, peuvent uniquement déclarer des constantes comment étant publiques.
PHP 7.1
##### Type de retour "void"
````php
function noReturn(): void {
// Valid
}
function nothing(): void {
return; // Valid too!
}
function outch(void $foo) {
// Fatal error.
}
function returnNull(): void {
return null; // Fatal error.
}
````
C'est le type de retour qu'il manquait depuis la sortie de PHP 7.0.
Vous pouvez maintenant indiquer qu'une fonction ne retourne rien.
PHP 7.1
##### Types "nullable"
````php
function response1(): ?int {
return null; // OK
}
function response2(): ?int {
return 42; // OK
}
````
````php
function response3(): ?int {
return new stdClass; // ERROR
}
// Le paramètre doit valoir un string ou être null
function dire(?string $message) {
if ($message) {
echo $message;
}
}
````
Bon, le retour de type "void" n'était pas le seul qu'il manquait. Mais le type nullable est un peu différent.
En effet, il permet de compléter un type de paramètre ou de retour en indiquant qu'il accepte en plus le type "null".
La sortie de PHP 7.1 signe également l'abandon de la librairie mcrypt (donc de toutes les fonctions type mcrypt_*),
le support des closures depuis des callable ou encore de l'ajout d'avertissements lors des conversions pendant les opérations arithmétiques.
## Tester une migration à PHP 7
Avant de sauter le pas, il faut tout d'abord rechercher les incompatibilités présentes dans votre projet.
Pour cela plusieurs solutions sont disponibles.
Tester une migration à PHP 7
php7cc
Outil en CLI
Installation par Phar, Composer ou Docker
Plus d'infos : https://github.com/sstalle/php7cc
php7cc ou PHP 7 Compatibility Checker est un outil en ligne de command prévu pour faire une migration depuis PHP 5.3-5.6 vers PHP 7 facilement.
Vous pouvez l'installer par phar, Composer ou Docker.
# Symfony
Symfony
Symfony
Sur ce tableau vous pouvez voir les versions de Symfony qui sont en LTS (Long Term Support) sur 36 mois (3 ans)
et qui donc supportent PHP 7 actuellement.
Symfony
Dans ces versions compatibles avec PHP 7, des fonctions obsolètes ont été supprimées et la version minimum de PHP
est désormais passée de 5.5 à 5.6.
Et comme je vous le disais, la version 2.8 en LTS intègre bien sûr les fonctionnalités de la version 3.0 en
conservant la rétro compatibilité avec les précendentes versions.
Symfony
## Changements
* Signatures de méthode
* Redéfinition de classes et méthodes
* Adaptation aux nouvelles normes PSR (php-fig.org)
* Modification de la structure des fichiers
Symfony
## Rappel sur les normes PSR
> PSR : Propose a Standards Recommendation
* PSR-0 : Chargement des classes PHP et autoloading
* PSR-1 : Conventions minimales de codage
* PSR-2 : Style et l'organisation du code
* PSR-3 : S'occupe de l'interface des loggers
* PSR-4 : Nouveau standard d'autoloading
* ...
*Source : http://www.php-fig.org/psr/*
Merci pour votre attention ! Des questions ?