Print Shortlink

PHP 5.4 est dans les bacs !

La version très attendue de PHP 5.4 est enfin sortie. De grandes améliorations étaient attendues pour cette nouvelle version. Attaquons nous en détails à ce qu’il ressort de cette nouvelle mouture :

  • La gestion des traits : afin de pallier aux limitations de l’héritage simple (l’héritage multiple n’étant pas disponible en PHP), les équipes de Zend ont défini des Traits. Ils permettent de définir des comportements réutilisables dans vos classes via le mot clé « use ».
  • Amélioration des fonctions d’array. Il est maintenant possible de définir un tableau directement via un $a = [1, 2 ,3 , 4] (plus besoin du mot clé array)
  • Intégration des closures ( $variable = function() ) aussi appelées fonctions anonymes ou fermetures
  • Un serveur web intégré pour le développement (et non la production)
  • <? fonctionnera maintenant quel que soit la configuration serveur
  • Il est maintenant possible de définir une variable en binaire directement à l’affectation $a = 0b0110010000
  • Une nette amélioration des messages d’erreurs (bien plus explicites)
  • Une amélioration de la gestion des sessions pour tracer en temps réel l’envoi de fichiers :)

Testons ces grandes nouveautés.

Les traits

L’héritage permet la réutilisation de code de classe en classe. Cependant, une limitation de PHP (et de d’autres langages du même type) est que cet héritage est « simple ». On entend par « simple » qu’il n’est possible, pour une classe donnée, de n’hériter que d’une seule autre classe.

PHP résout aujourd’hui ce problème en introduisant la notion de « traits ». Ce ne sont pas des classes mais des définitions de comportement, puisqu’un trait n’est pas instanciable. Les traits sont définis par le mot clé « trait » et importés dans une classe grâce au mot clé « use ».

Prenons un exemple concret :

<?
trait UtilisateurWeb{
function getNomUtilisateur(){ /* Algo de récupération de nom d’utilisateur */}
function isSessionExpiree() { /* Algo de vérification de session */ }
}
Class Personne{
	function getNom() { /* Récupère le nom de l’utilisateur */ }
	function getPrenom() { /* Récupère le prénom de l’utilisateur */}
}
Class AdministrateurWeb extends Personne{
	use UtilisateurWeb ;
	function toString() {
		return « Utilisateur » + getNomUtilisateur()+ «  [nom= »+ getNom()+ « ,prenom= »+getPrenom()+  « ] » ;
	}
}
?>

Une classe peut utiliser autant de traits que nécessaire, la réutilisation de code est donc ici clairement maximisée.

Posons-nous quelques questions :

  • Si un trait et une classe héritée ont le même nom de méthode, quelle méthode prime ?

Le trait prime.

  • Peut-on utiliser un trait mais sans hériter d’une classe

Sans problème !

  • Un trait peut-il utiliser des traits ?

Oui !

Amusez-vous bien :)

Les fonctions anonymes

Très utilisées en Javascript pour définir des fonctions callback, les closures apparaissent aujourd’hui dans PHP.

<?php
$greet = function($name)
{
    printf("Bonjour %s\r\n", $name);
};
 
$greet('World');
$greet('PHP');
?>

Pour les développeurs Python ou C#, vous vous y retrouverez puisque c’est la même utilisation que vos expressions lambdas.

Attaquons nous à une illustration un peu plus avancée que l’utilisation « Hello Worldienne ». Comment ordonner une liste de nombres en PHP ?

<?
// Méthode classique de tri
function comp($a, $b) {
    return($a > $b);
}
uasort($array, 'comp');
 
// Maintenant
uasort($array, function($a, $b) {
    return($a > $b);
});
?>

Simple et efficace !

Mais les fonctions anonymes ouvrent aussi la voix à l’asynchrone, nos fonctions d’entrées/sorties ou d’appels en bases de données pourraient se retrouver plus facilement en asynchrone, permettant des gains de performance importants.

Les tableaux

Jusqu’à cette nouvelle version de PHP, les tableaux en PHP se définissaient de la manière suivante :

$montableau = array ( 1, 2 , 3 ) ;

De la même façon, un dictionnaire se définissait comme ceci :

$mondictionnaire = array ( 1 => « toto », 2 => « titi » , 3 => « tata » ) ;

Dans la version 5.4 de PHP, le mot clé array a été remplacé par de simples crochets []

Nous écrirons donc un tableau et un dictionnaire de la façon suivante :

$montableau = [ 1, 2 , 3 ] ;

$mondictionnaire = [ 1 => « toto », 2 => « titi » , 3 => « tata » ];

Pas transcendant, mais tout de même plus rapide.

Il est maintenant possible de récupérer la nième case d’un tableau en sortie de fonction.

Exemple :

<?php
function getArray() {
    return array(1, 2, 3);
}
 
$tmp = getArray();
$secondElement = $tmp[1];
 
?>

Un peu long. Maintenant en PHP 5.4 :

<?php
function getArray() {
    return array(1, 2, 3);
}
 
$secondElement = getArray()[1];
 
?>

Mieux !

 

Suivre la progression d’un téléchargement en temps réel

Lorsque nous téléchargeons un fichier (envoi ou réception d’ailleurs), il n’est pas possible de savoir aujourd’hui où nous en sommes dans le téléchargement.

Prenons un cas concret : une application web (ajax) comme un client mail. A l’envoi d’un mail, nous voulons pouvoir joindre une pièce jointe. Comment afficher une barre de progression à l’utilisateur ?

Il va falloir lancer deux opérations :

  1. Faire une requête POST d’envoi du fichier
  2. Faire une seconde requête pour savoir où en est le téléchargement

Pour la première opération, pas de problèmes.

Pour la seconde par contre, avant PHP 5.4, nous n’avions pas de moyen simple de savoir où nous en étions dans le téléchargement. Il fallait aller lire le fichier en cours d’écriture et récupérer la taille envoyée. Avec la taille totale, il était possible de calculer le taux de progression et donc de dessiner une barre de progression sur le navigateur.

A partir de PHP 5.4, nous avons à disposition une variable dans la session nous indiquant toutes les informations nécessaires. Cette variable est disponible aussitôt que l’option session.upload_progress.enabled est à true dans votre fichier de configuration PHP.

Partons de notre formulaire d’envoi de mails :

Fichier form.html :

<form action="sendmail.php" method="POST" enctype="multipart/form-data">
 <input type="hidden" 
        name="<?php echo ini_get("session.upload_progress.name"); ?>" 
        value="123" />
 <input type="file" name="piecejointe" />
 <input type="text" name="destinataire" />
 <input type="submit" />
</form>

 

Fichier sendmail.php

<?php
$key = ini_get("session.upload_progress.prefix").ini_get("session.upload_progress.name");
var_dump($_SESSION[$key]);
?>

Que s’affichera à l’écran ?

<?php
$_SESSION["upload_progress_123"] = array(
 "start_time" => 1234567890,   // L'heure de la requête
 "content_length" => 57343257, // Longueur du contenu POST
 "bytes_processed" => 453489,  // Quantité d'octets reçus et traités
 "done" => false,              // true lorsque le gestionnaire POST a terminé, avec succès ou non
 "files" => array(
  0 => array(
   "field_name" => "piecejointe",       // Nom du champ <input/>
   // Les 3 éléments suivants sont équivalents à ceux dans $_FILES
   "name" => "formation_php_mistra.pdf",
   "tmp_name" => "/tmp/phpxxxxxx",
   "error" => 0,
   "done" => true,                // True lorsque le gestionnaire POST a terminé de gérer ce fichier
   "start_time" => 1234567890,    // L'heure de début de requête
   "bytes_processed" => 57343250, // Quantité d'octets reçus et traités pour ce fichier
  )
 )
);

Que du bonheur :-)

Serveur web intégré

Lors des débuts d’un développeur en programmation, les notions de client/serveur sont assez complexes à acquérir. Lors de nos formations PHP, nous devons expliquer pourquoi, pour une formation PHP, nous devons installer un système WAMP (Windows Apache MySQL PHP) entier pour utiliser un langage.

Et même si Apache s’installe très facilement, a-t-on besoin d’une telle usine à gaz pour la phase de développement de notre projet ? C’est l’idée de l’équipe PHP qui a décidé de nous mettre à disposition, pour les phases de développement, un serveur minimaliste pouvant interpréter nos projets PHP.

Pour lancer notre serveur, un simple « php –S localhost:8888 » et hop , nous pouvons voir nos logs web (l’équivalent des fichiers access.log) directement dans la console.

 

Fonctionnalités obsolètes

Les fonctions mcrypt_generic_end() et mysql_list_dbs() sont dorénavant obsolètes dans PHP 5.4

Gaetan
View all posts by Gaetan