Ceux qui suivent les dernières avancées du langage PHP connaissent les différents débats ayant eu lieu ces derniers temps quant à la syntaxe des namespaces, de la syntaxe tabulaire …
Cette semaine a été annoncée la version RC1 de PHP5.3.0, dont la version finale devrait sortir (selon des « experts ») cet été ou à la rentrée prochaine. Je vous propose de regarder de manière simple et concrète les belles choses que cette version nous amène !
Nous regarderons ainsi les espaces de noms (namespaces), la syntaxe Nowdoc (dans la lignée de Heredoc), le nouveau raccourci pour la syntaxe ternaire, les fonctions anonymes, la résolution statique à la volée … et la déclaration de tableaux ?
L’annonce officielle
Voici tout d’abord la liste officielle des nouveautés avant de se focaliser sur les points essentiels :
The key features of the PHP 5.3 branch include:
- Support for namespaces
- Under the hood performance improvements
- Late static binding
- Lambda functions and closures
- Syntax additions: NOWDOC, limited GOTO, ternary short cut « ?: » and __callStatic()
- Optional garbage collection for cyclic references
- Optional mysqlnd PHP native replacement for libmysql
- Improved windows support including VC6 and VC9 binaries
- More consistent float rounding
- Deprecation notices are now handle via E_DEPRECATED (part of E_ALL) instead of the E_STRICT error level
- Several enhancements to enable more flexiblity in php.ini (and ini parsing in general)
- New bundled extensions: ext/phar, ext/intl, ext/fileinfo, ext/sqlite3, ext/enchant
- Countless bug fixes and improvements to existing extensions in particular to: ext/openssl, ext/spl and ext/date
This release also drops several extensions and unifies usage of internal APIs. Users should be aware of the following known backwards compatibility breaks:
- Parameter parsing API unification will cause some functions to behave more or less strict when it comes to type juggling
- Removed the following extensions: ext/mhash (see ext/hash), ext/msql, ext/pspell (see ext/enchant), ext/sybase (see ext/sybase_ct)
- Moved the following extensions to PECL: ext/ming, ext/fbsql, ext/ncurses, ext/fdf
- Removed zend.ze1_compatibility_mode
- See the upgrading guide for other minor changes
… reprenons les principaux points pour voir concrètement ce que donneront nos codes.
Les namespaces
Les namespaces permettent de différencier deux classes, méthodes, constantes ou autres éléments ayant le même nom mais des signification différentes.
Imaginons que je récupère une bibliothèque codée par une autre personne et ayant une classe ‘MaClassePratique’ que j’inclus partout dans mon projet. Désormais, si je souhaite créer une classe ‘MaClassePratique’ dans mon projet, cela sera impossible car il y aura un conflit de noms. Voici l’exemple de code associé :
<?php // fichier /librairies/utilitaires/ma_classe_pratique.php class MaClassePratique { // Patati patata ... } ?>
<?php // fichier /classes/ma_classe_pratique.php class MaClassePratique { // Patati patata ... } ?>
<?php // fichier /mon_fichier.php $mcp = new MaClassePratique(); // Nous aurons droit à une erreur car PHP ne sait pas quelle classe utiliser ?>
NOTE aux puristes : en fait l’erreur devrait être levée à la déclaration de la classe personnelle en disant « une classe du même nom existe déjà »
Les espaces de noms (namespaces) permettent de résoudre ce problème en ajoutant un « chemin » (vous verrez que la syntaxe ressemble aux dossiers Windows) encadrant la classe. Ainsi, chaque librairie aura son propre espace de noms afin d’éviter les conflits. Voici le code ci-dessus tel qu’il serait adapté :
<?php // fichier /librairies/utilitaires/ma_classe_pratique.php namespace Utilitaire\Pratique\Auteur; class MaClassePratique { // Patati patata ... } ?>
<?php // fichier /classes/ma_classe_pratique.php namespace Mon\Projet\Section; class MaClassePratique { // Patati patata ... } ?>
<?php // fichier /mon_fichier.php $mcp = new Mon\Projet\Section\MaClassePratique(); // Nous aurons instancié notre propre classe $mcp2 = new Utilitaire\Pratique\Auteur\MaClassePratique(); // Nous aurons instancié la classe de la bibliothèque (écrite par un tiers) ?>
Notons au passage qu’il n’est bien entendu pas obligatoire de déclarer des espaces de noms pour toutes vos classes (votre code actuel sera donc compatible, n’ayez pas peur). Pour en savoir plus, visitez la documentation PHP.
La syntaxe Nowdoc
Comme dit dans la documentation :
Nowdoc est aux chaînes entourées de guillemet simple ce qu’Heredoc est aux chaînes entourées de guillemet double
Cela sert donc à déclarer des chaînes de caractères sur plusieurs lignes sans se soucier des guillemets.
<?php // syntaxe Heredoc existant depuis PHP4 class foo { var $foo; var $bar; function foo() { $this->foo = 'Foo'; $this->bar = array('Bar1', 'Bar2', 'Bar3'); } } $foo = new foo(); $name = 'MyName'; echo <<EOT Mon nom est "$name". J'affiche quelques $foo->foo. Maintenant, j'affiche quelques {$foo->bar[1]}. Et ceci devrait afficher un 'A': \x41 EOT; /* Affichera : Mon nom est "MyName". J'affiche quelques Foo. Maintenant, j'affiche quelques Bar2. Et ceci devrait afficher un 'A' majuscule : A */ ?>
Et désormais nous pouvons faire exactement pareil avec la syntaxe Nowdoc mais les variables ne seront pas interprétées. Il suffit de remplacer » EOT » par » ‘EOT’ » :
<?php // syntaxe Nowdoc introduite en PHP 5.3 // [...] Idem ci-dessus echo <<<'EOT' Mom nom est "$name". J'affiche quelques $foo->foo. Maintenant, j'affiche quelques {$foo->bar[1]}. Ceci ne devrait pas afficher un 'A': \x41 EOT; /* Affichera Mom nom est "$name". J'affiche quelques $foo->foo. Maintenant, j'affiche quelques {$foo->bar[1]}. Ceci ne devrait pas afficher un 'A': \x41 */ ?>
Une syntaxe bien pratique à mettre entre toutes les mains … mais je me demande pourquoi ils n’y avaient pas pensé avant.
Une nouvelle syntaxe ternaire
Je sais que beaucoup de gens n’aiment pas cette syntaxe, mais personnellement je trouve que c’est un des trucs les plus pratiques des langages de programmation. Petit rappel de ce que cela donne :
<?php // Choix vaut "true" ou un message d'erreur en fonction de la valeur du résultat $resu = fait_quelquechose(); $retour = ($resu) ? true : 'Pas glop !'; ?>
Désormais on peut simplifier cette ligne grâce à l’opérateur « ?: », ce qui donnerait :
<?php // Choix vaut "true" ou un message d'erreur en fonction de la valeur du résultat $retour = (fait_quelquechose()) ?: 'Pas glop !'; ?>
… bon d’accord c’est sale, mais assez clair je trouve une fois qu’on a l’hébitude
Par contre d’autres langages (j’avais utilisé ça en C# je crois) fournissent un raccourci pour ceci :
<?php $action = (empty($_POST['action'])) ? 'default' : $_POST['action']; ?>
Si vous connaissez l’équivalent en PHP, je suis preneur !
Mais aussi …
… d’autres choses intéressantes qu’il serait inutile de décrire ici car c’est très bien décrit dans la documentation :
- La résolution statique à la volée : permettant de résoudre les problèmes liés à l’appel de méthodes statiques de classes ayant été surchargées, grâce à l’introduction du mot clé « static:: ».
- Les méthodes anonymes un premier pas vers la programmation fonctionnelle en PHP ?! En tout cas cela facilite la vie dans le cadre d’utilisation des méthodes de rappel (callback)
N’aurions nous pas la nouvelle syntaxe pour la déclaration des tableaux ?
Il y a eu de (trop) longues discussions sur la mailing list php-internal à ce sujet, où même notre grand gourou Nate Abele s’était exprimé
!
Voici la proposition de nouvelle syntaxe qui me semble vraiment pratique également :
<?php $var = array(1,2,3); // Actuellement $var = [1,2,3]; // Nouvelle syntaxe ? // ... en effet, les chaînes de caractères se déclarent bien comme ça : $chaine = 'patati'; // et non comme ceci : $chaine = string('patati'); ?>
Je ne suis pas arrivé à connaître la décision finale … si vous le savez, vous serie gentils de me la faire parvenir !
Que pensez-vous de toutes ces nouveautés ? Pratique, inutile ?
If you enjoyed this post, make sure you subscribe to my RSS feed! Tags : php
