Prenez la version 5.2.6 de PHP.

Donnez lui à manger le code suivant :

<?php

error_reporting(E_STRICT);

abstract class truc implements iteratorAggregate
{
function __construct() {}

function load(array $array)
{
echo uniqid();
}

function getIterator()
{
return array();
}
}

class extendedTruc extends truc
{
function __construct() { parent::__construct(); }

function load($id)
{
return parent::load(array('id' => $id));
}
}

$truc = new extendedTruc();

$truc->load(rand(1, PHP_INT_MAX));

?>

Vous n'aurez aucun problème.

Maintenant, donnez à manger le même code à la version 5.2.10 de PHP.

Vous allez vous prendre en pleine tête la jolie erreur suivante :

PHP Strict standards:  Declaration of extendedTruc::load() should be compatible with that of truc::load() in /usr/home/fch/tmp/test.php on line 20

Encore plus fun : supprimez la déclaration de l'interface iteratorAggregate de votre classe truc et donner à manger cette nouvelle version du code à la version 5.2.10 de PHP.

Vous n'aurez plus aucune erreur...

En gros, si vous déclarez une interface sur une classe de base, l'adéquation des signatures des méthodes des classes dérivées avec les signatures des méthodes de la classe de base sera vérifiées de manière très stricte si et seulement si une interface est déclarée au niveau de la classe de base, et ce même pour les méthodes qui ne font pas parties de l'interface.

Et après cela, il y en a encore qui vont dire que j'éxagère lorsque je dis que PHP, c'est de la merde...

Pour ceux que ca intéresse, le code fonctionnellement identique qui s'éxécute sans erreur avec la version 5.2.10 de PHP est le suivant :

<?php

error_reporting(E_STRICT);

abstract class truc implements iteratorAggregate
{
function __construct() {}

function load($array)
{
if (is_array($array) === false)
{
trigger_error('First argument must be an array.', E_USER_ERROR);
}
else
{
echo uniqid();
}
}

function getIterator()
{
return array();
}
}

class extendedTruc extends truc
{
function __construct() { parent::__construct(); }

function load($id)
{
return parent::load(array('id' => $id));
}
}

$truc = new extendedTruc();

$truc->load(rand(1, PHP_INT_MAX));

?>

Par contre, je vous laisse trouver l'horreur qu'il faut écrire pour pouvoir donner une valeur par défaut à l'argument de la méthode extendedTruc::load() sans avoir d'erreur.

Et si quelqu'un peut tester avec la version 5.3.x et me mettre en commentaire de ce billet le résultat, je l'en remercie d'avance.