RFC: Scalar Type Declarations (v0.5)

L’idée d’introduire des type-hints scalaires pour les paramètres de fonctions et méthodes est revenue plusieurs fois sur le devant de la scène ces dernières années.

Une première RFC « Scalar Type Hints » a récemment été jusqu’à la phase de votes (ceux-ci étant particulièrement serrés avec un nombre record de participants), mais a été retirée suite au départ de son auteur.

La demande de type-hints scalaires étant visiblement forte au niveau de la communauté (au vu des échanges sur twitter, du nombre de blog-posts sur le sujet, des réactions sur reddit, …), Anthony Ferrara a relancé l’idée quelques jours plus tard, avec une RFC forkée depuis celle d’Andrea :

Cette nouvelle version de la RFC introduisait quelques différences relativement mineures par rapport à la précédente version 0.3, qui était en cours de vote une semaine avant :

  • L’instruction declare() doit désormais être la première du fichier.
  • Elle ne peut plus être utilisée en mode bloc ; seulement en mode fichier entier.
  • Les aliases integer et boolean ont été supprimés.
  • Et un entier est maintenant considéré comme valide pour le type-hint float ; y compris en mode strict.

Une longue section « Discussion points » a également été ajoutée, visant à répondre à de nombreuses questions habituelles sur le sujet et la proposition.

L’adoption de cette RFC demandait une majorité des 2/3 des voix. Les votes ouvert le 26 février ont été clôturés le 13 mars 2015. Comme pour la version précédente de cette proposition, nous avons exprimé un avis positif sur internals@.

Finalement, avec 108 votes « pour » et 48 votes « contre » (un tel nombre de votes, c’est un record !), cette RFC a été acceptée ! PHP 7.0 disposera donc de type-hints scalaires !

RFC: Generator Return Expressions

Voici une première RFC qui visait à élargir le périmètre fonctionnel des générateurs ajoutés avec PHP 5.5 :

Note : cette proposition conditionne la RFC Generator Delegation, qui a été rédigée quelques jours plus tard.

Cette RFC proposait de permettre aux fonctions générateur l’utilisation de return avec une valeur (ce qui provoque aujourd’hui une Fatal Error). Une méthode Generator::getReturn() serait alors ajoutée pour permettre l’obtention de cette valeur de retour. Elle ne pourrait bien sûr être appelée qu’une fois la fonction génératrice terminée.

En somme, cela permettrait d’avoir une vraie valeur de retour explicite pour les générateurs, plutôt que de considérer que la dernière valeur yieldée joue ce rôle.

Les votes ont été ouvert le 09 mars pour être clôturés le 16 Mars 2015. Nous avons exprimé un avis positif sur internals@.
Et cette RFC a été acceptée à l’unanimité (33 votes « pour » et 0 vote « contre »).

RFC: Make empty() a Variadic

Voici une courte RFC autour de la construction empty() :

Cette RFC partait de l’idée qu’il est commun de vouloir utiliser empty() sur plusieurs variables, en vue de déterminer si l’une d’entre elles est vide ou si aucune ne l’est ; ce qui passe actuellement par une portion de code de ce type :

if (empty($a) || empty($b) || empty($c)) {
    // Une des variable est vide
}

if (!empty($a) && !empty($b) && !empty($c)) {
    // Aucune variable vide
}

Pour simplifier l’écriture de ce type de test, cette RFC proposait de rendre empty() variadique (comme l’est déjà isset()), ce qui permettrait d’utiliser l’écriture suivante :

if (empty($a, $b, $c)) {
    // Une des variable est vide
}

if (!empty($a, $b, $c)) {
    // Aucune variable vide
}

Passer plusieurs expressions à empty() reviendrait à effectuer un OR entre empty() de chaque expression.

Les votes ont été ouverts le 7 mars 2015 pour être clôturés le 21 mars. Considérant que cette proposition apporterait un fort risque de confusion (est-ce qu’on vérifie qu’au moins une donnée est vide ? Ou est-ce qu’on vérifie que toutes les données sont vides ?), nous avons exprimé un avis négatif sur internals@.

Une majorité des 2/3 était requise pour l’adoption de cette RFC et elle a été rejetée, avec 26 votes « pour » et 26 votes « contre ».

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 : Improve array to string conversion

Voici une RFC qui tourne autour de la conversion de tableaux (array) en chaînes (string) : Improve array to string conversion

Cette RFC partait du constat que, aujourd’hui, convertir un array vers une string entraîne la levée d’une E_NOTICE et donne « Array » comme résultat… Autrement dit, une chaîne peu utile et seulement une semi-erreur.

Elle proposait au départ deux alternatives (opposées) visant à éliminer ce comportement problématique :

  • Interdire totalement la conversion array → string en levant une « catchable fatal error« , comme c’est déjà le cas pour la conversion object → string pour les classes n’ayant pas de méthode __toString().
  • Supporter réellement la conversion arraystring, en déterminant et implémentant un algorithme réalisant la conversion.

Après discussions sur internals@, la seconde option a été supprimée avant l’ouverture des votes, qui n’ont donc porté que sur la première.

Considérant que la conversion array → string n’était que rarement voulue et correspondait quasiment toujours à des cas de bugs, nous avons indiqué sur internals@ que nous étions en faveur de cette proposition.
La RFC a finalement été acceptée, avec 34 votes « pour » et 10 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: Expectations

Voici une RFC destinée à servir principalement en environnements de développement :

L’idée derrière cette RFC, basée sur la fonction assert(), est de permettre l’exécution de code de débogage, en développement uniquement. Cela permettrait à la fois d’identifier des problèmes (encore une fois, en environnements de développement) et de documenter le code. Plusieurs exemples illustrant les différents cas d’usage sont donnés dans la RFC.

En cas d’échec, la condition spécifiée en premier paramètre de assert() n’étant pas vraie, une exception de type AssertException (soit spécifiée en second paramètre, soit générée automatiquement) sera levée — passer par une exception plutôt qu’une erreur permettant d’obtenir plus facilement une stacktrace.

L’activation ou non des assertions serait paramétrée par le biais d’une directive .ini nommée zend.assertions, qui pourrait valoir :

  • 1 : pour générer et exécuter le code correspondant aux assertions : c’est la valeur qui sera généralement utilisée en environnement de développement
  • 0 : pour générer le code mais ne pas l’exécuter
  • -1 : pour ne pas du tout générer le code de l’assertion (coût nul, à utiliser en production)

L’API proposée par cette RFC est globalement compatible avec celle actuellement en place pour la fonction assert() existante : il s’agit surtout d’améliorer celle-ci, notamment en supprimant complétement la génération et l’exécution du code de l’assertion en mode « production ».

Les votes se sont tenus du 19 au 26 février et nous avons exprimé un avis plutôt négatif sur internals@, considérant principalement que mélanger le code et les tests n’était pas l’approche qui nous semblait la meilleure et ne souhaitant donc pas encourager l’utilisation de assert().
Les résultats ont finalement été les suivants, cette RFC est donc passée :

  • 20 « oui » avec exceptions personnalisées
  • 11 « oui » sans exception personnalisée
  • 1 seul et unique « non »

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.