Bonjour,

Je rencontre un comportement bizarre lors de l'interprétation de mon script php. Dans une classe Front_Dispatcher, j'ai un constructeur et une méthode qui sont censées recevoir chacune un argument de type Front_Router.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Front_Dispatcher
extends Abstract_Strategy
implements Interface_Observer
{
    public function __construct( Front_Router $router )
    {
        $router->attach( $this );
        parent::__construct( $router );
    }
 
    public function update( Front_Router $observable )
    {
        print "updating std_dispatcher";
    }
}
Seulement je rencontre un problème avec l'une de ces deux méthodes :

Fatal error: Declaration of Front_Dispatcher::update() must be compatible with that of Interface_Observer::update() in C:\Documents and Settings\alejandro\Mes documents\WebApps\www\system\Front\Dispatcher.php on line 5
L'interface Interface_Observer déclare la méthode update suivante :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
public function update( Interface_Observable $observable );
Donc je me dis que même si Front_Router implémente Interface_Observable via son parent Abstract_Observable, cela ne fonctionne pas :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
class Front_Router
extends Abstract_Observable
implements Interface_Strategy
{
    public function execute()
    {
        $this->notify();
    }
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
abstract class Abstract_Observable
implements Interface_Observable
Sauf que ...

En ce qui concerne ma fonction __construct, qui requiert également un objet de type Front_Router, je n'ai pas de message d'erreur, alors que je demande un argument de type Interface_Strategy dans son parent Abstract_Strategy :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
abstract class Abstract_Strategy
implements Interface_Strategy
{
    protected $_strategy;
 
    public function __construct( Interface_Strategy $strategy )
    {
        $this->_strategy = $strategy;
    }
 
    public function execute()
    {
        $this->_strategy->execute();
    }
}
Sauf que, différence avec update, là je l'implémente directement dans le Front_Router mon Interface_Strategy, ce qui fait qu'il a l'air de me le prendre.

Donc ma question est la suivante : Pourquoi ça marche dans un sens et pas dans l'autre ? Est-ce une insuffisance de PHP ou un défaut de conception venant de ma part ?

Sachant également que si je modifie ma fonction update dans Front_Router comme suit mon problème est réglé et tout fonctionne correctement :

public function update( Interface_Observable $observable )
Simplement je voudrais contraindre mon argument à être de type Front_Router ou d'une classe qui en hériterais, afin de pouvoir utiliser certaines méthodes spécifiques à tous les Front_Routers mais pas forcément à un objet implémentant Interface_Observable.

Votre avis ?