Tous les articles par Guillaume

RFC: Context Sensitive Lexer

La RFC: Context Sensitive Lexer partait du constat qu’il existe actuellement 64 mots clefs réservés par PHP et que certains d’entre eux seraient très utiles en tant que noms de méthodes, pour définir des API claires côté utilisateur.

Elle proposait donc de modifier l’analyse du code PHP afin de disposer d’une analyse lexicale sensible au contexte, permettant l’utilisation de mots clefs ; en se limitant pour l’instant au périmètre de la programmation objet :

// Le code suivant devient possible:
interface Collection
{
    public function forEach(callable $callback);

    public function list();
}

// Mais pas le suivant:
function list() {/* */}

De plus, cette RFC permettrait également de limiter les problèmes de rétro-compatibilité à l’avenir, lorsque PHP réservera de nouveaux mots clefs.

Considérant que pouvoir utiliser des mots-clefs comme noms de classes ou de méthodes était intéressant, nous avons (à l’unanimité !) posté en ce sens sur internals@.
Cette RFC a été acceptée pour PHP 7.0, avec 36 votes « pour » et 12 votes « contre ».

 

 

RFC: Exceptions in the engine

La RFC: Exceptions in the engine visait à généraliser l’utilisation d’exceptions dans le moteur PHP ainsi qu’à transformer en exceptions la plupart des erreurs fatales, ce afin de laisser aux applications la possibilité de contrôler ces erreurs.

Cette RFC introduisait pour cela deux nouveaux types d’exceptions :

  • EngineException : type d’exception générique générée par le moteur PHP
  • ParseException : exception générée lorsque le code PHP ne peut être traité

À cela s’ajoute une classe de base, abstraite, BaseException, qui viendrait se mettre en place dans la hiérarchie des exceptions comme suit :

BaseException (abstract)
 +- EngineException
 +- ParseException
 +- Exception
     +- ErrorException
     +- RuntimeException
         +- ...
     +- ...

Les blocs attrapant les exceptions de type Exception n’attraperaient pas ces nouvelles exceptions, ne générant ainsi aucun effet de bord côté utilisateur.

Il est ressorti de nos échanges que nous étions en très large majorité en faveur de cette RFC et avons donc posté en ce sens sur internals@.

Avec 60 voix pour et seulement 2 contre, cette RFC a été accepté et sera mise en place dans la version 7 de PHP.

RFC: Remove PHP 4 Constructors

La RFC: Remove PHP 4 Constructors, comme son nom l’indique, visait à supprimer les constructeurs introduits dans la version 4 de PHP, où la méthode de construction des objets était appelée comme la classe elle-même :

class Filter
{
    // Constructor as introduced in PHP 4
    function filter() {}
}

Ce comportement, qui induit souvent en erreur les développeurs, est depuis longtemps vu par beaucoup comme indésirable. Néanmoins, sa suppression visant (initialement) la version 7 de PHP fut génératrice d’interrogations, notamment à cause de son utilisation récurrente dans les extensions PEAR ou même sur WordPress.

Ce sujet a également animé les débats sur internals@ et la RFC a évolué pour passer en deux phases :

  • PHP 7 : les anciens constructeurs génèreront un avertissement de type E_DEPRECATED
  • PHP 8 : suppression des anciens constructeurs qui deviendront alors de simples méthodes.

Suite à cette mise à jour, les derniers doutes furent levés et nous avons majoritairement approuvé cette RFC, postant dans ce sens sur internals@.

Avec 49 voix pour  et seulement 4 contre, la dernière version de la RFC a été acceptée, devenant la toute première RFC validée ayant comme version cible PHP 8 !

 

RFC: Allow error_handler callback parameters to be passed by reference

La RFC: Allow error_handler callback parameters to be passed by reference avait pour objectif de permettre aux gestionnaires d’erreurs configurés via set_error_handler() de modifier les informations de l’erreur gérée, en passant ses valeurs par référence.

L’objectif était de pouvoir y passer des informations contextuelles de type identifiant stocké en session, URL parcourue lors de l’erreur, etc. de la manière suivante:

$_SESSION['username'] = 'john';
 
function myErrorHandler($errno, &$errstr, $errfile, $errline)
{
  if (isset($_SESSION['username'])) {
    $errstr .= ', username: '.$_SESSION['username'];
  }
  return false; // continue normal error handler
}
 
set_error_handler('myErrorHandler');

La RFC n’a pas convaincu et nos avis furent tous négatifs, principalement dû au fait que cette gestion pouvait être très facilement déléguée à la fonction utilisateur sans forcément avoir recours à des paramètres passés par référence. Nous avons donc posté en ce sens sur internals@.

La RFC proposait deux choix possibles : passer uniquement le message d’erreur par référence, ou bien l’ensemble des paramètres. Quoi qu’il en soit, avec 19 voix contre et 4 pour, la RFC a été rejetée.

RFC: Add pecl_http to core

La RFC: Add pecl_http to core avait pour objectif d’intégrer nativement à PHP 7 l’extension pecl_http. Cette extension permet de gérer des communications HTTP grâce à une implémentation orientée objet.

Néanmoins, la présence de curl permettant l’accès à la couche HTTP à bas-niveau ainsi que l’existence de bibliothèques comme Guzzle  apportant une implémentation orientée objet (en espace utilisateur, donc non liée au cycle de versions et de maintenance de PHP) nous a paru suffisant en l’état. De plus, l’extension pecl_http embarquait des dépendances qui seraient venues s’ajouter au cycle de maintenance de PHP. Nous avons donc posté en ce sens sur internals@.

Avec 9 voix pour et 23 voix contre, cette RFC a finalement été refusée : l’extension pecl_http restera disponible depuis PECL pour les intéressés, et ne sera pas distribuée avec PHP.

RFC: Remove the date.timezone warning

La RFC Remove the date.timezone warning partait du constat qu’il existe à l’heure actuelle une directive de configuration qui nécessite d’être définie afin de pouvoir lancer PHP sans erreur : date.timezone.

Lorsque cette directive n’est pas configurée, une erreur de type warning est générée par PHP, même si le moteur lui attribue une valeur par défaut (UTC).

Le but de cette RFC était de supprimer cette erreur, afin de pouvoir fournir à PHP une installation paramétrée complète par défaut. En effet, il apparaît que de nombreuses autres directives, bien plus sensibles notamment en terme de sécurité, sont d’ores et déjà configurées par défaut.

Il nous semblait que l’absence de configuration de cette directive devait à minima générer une erreur stricte, car elle impacte des fonctions de date très usitées (telle date()), d’autant que la zone par défaut est aujourd’hui définie de manière arbitraire. Nous avons donc répondu en ce sens sur internals@.

Néanmoins, avec 32 votes pour et 11 contre, cette RFC est passée et l’avertissement correspondant ne sera donc plus levé à partir de PHP 7.

RFC: PHP 5.7

Le but de la RFC PHP 5.7 était de créer la version susnommée afin de simplifier la transition vers la version 7 qui avait été actée.
Il était prévu pour cette version mineure de générer des avertissements E_DEPRECATED pour les fonctionnalités dépréciées ainsi que réserver des mots-clefs introduits par PHP 7. Celle-ci n’apporterait aucune nouvelle fonctionnalité.

Nous avons, pour la majorité, été convaincu par les deux principaux arguments de cette RFC :

  • les applications pouvaient aisément résoudre les problèmes de compatibilité apportés par PHP 7 avant même que celle-ci soit officiellement disponible, accélérant ainsi son adoption
  • l’ajout d’une année supplémentaire au support de PHP 5, qui se termine actuellement en août 2017, aurait permis d’assurer à la version PHP 5 des correctifs, notamment de sécurité, jusqu’en 2018.

Confrontée aux statistiques d’utilisations de PHP proposées par Pascal Martin, des arguments contraires se sont toutefois fait entendre à l’encontre de cette RFC. En effet, il apparaît que les deux versions PHP les plus utilisées aujourd’hui sont PHP 5.2 et PHP 5.3 ; l’ajout d’une version 5.7 n’aurait donc eu vraisemblablement que peu d’incidence sur l’adoption de PHP 7.

Nous avons donc donné un avis relativement partagé sur internals@, précisant que le plus important restait toutefois la sortie de PHP 7.

La RFC a été rejetée par 19 voix contre 14, car pour l’heure, PHP 7 n’intègre pas suffisamment de problèmes de rétrocompatibilité pour justifier une version 5.7.
Néanmoins, les échanges sur internals@ ont laissé entendre que si des RFC générant des problèmes majeurs de rétrocompatibilité venaient à être intégrées au périmètre de PHP 7, une RFC à propos de PHP 5.7 pourrait se voir offrir une seconde chance et un nouveau vote.

RFC: Static classes

La RFC Static classes partait du constat qu’il est aujourd’hui possible de créer des classes avec propriétés et méthodes statiques uniquement, mais qu’il est impossible de les définir comme non instanciables sans passer par un constructeur privé, ce qui rend notamment ces classes non testable.

Le but de cette RFC était d’ajouter un mot clef static au niveau de la classe afin de définir l’intégralité de son comportement comme tel :

static class Environment
{
    private $rootDirectory = '/var/www/project';
    public function getRootDirectory()
    {
        return self::$rootDirectory;
    }
}

Notons toutefois qu’aujourd’hui, un tel comportement est presque possible en utilisant une classe abstraite :

abstract class Environment
{
    static private $rootDirectory = '/var/www/project';
    static public function getRootDirectory()
    {
        return self::$rootDirectory;
    }
}

Néanmoins, cette syntaxe présente plusieurs limites que la RFC souhaitait couvrir :

  • il est possible d’oublier un mot-clef static
  • la classe peut être étendue et donc instanciée par le biais d’une classe fille, la rendant non statique : il faudrait y ajouter le mot clef final.

C’est pour cette raison que la RFC fut lancée sous le nom de Abstract Final class. Le but premier était de donner la possibilité de rendre une classe abstraite finale.

Le principe fut rejeté car une classe abstraite a pour but même d’être étendue alors qu’une classe finale ne peut pas l’être !
C’est pour cette raison qu’après moult échanges en interne, la RFC fut proposée une nouvelle fois sous son nouveau nom, afin d’ajouter un nouveau mot clef pour lever toute incompréhension.

S’il est vrai que définir une classe comme statique dès sa déclaration à l’avantage indéniable de clarifier son rôle, il est toutefois ressorti de nos échanges qu’il semblerait que la plupart des cas d’utilisation étaient des collections de fonctions, parfois appelées helpers. La majorité fut contre cette demande, principalement car les classes statiques ne sont pas reconnues comme une pratique à encourager. Nous avons donc posté en ce sens sur internals@.

La RFC a été rejetée par 12 voix contre 5. Toutefois,  même si cette proposition voulait couvrir un périmètre plus large, le chargement automatique des fonctions est un sujet qui est ressorti plusieurs fois au cours de nos discussions. Un souhait visiblement partagé par de nombreux développeurs.