Les traits s'approchent tranquillement avec PHP 5.4, mais il s'agit encore de quelque chose très statique.

Pour ceux qui proviennent du monde de Java, vous êtes sans doute famillier avec le concept d'aspect. C'est à dire d'avoir une classe de base, et dynamiquement (pendant le run time) la spécialiser en lui implémentant des aspects.

Cette notion ne semble pas encore exister en PHP, et coté sémantique, ca promet toute une panoplie de problèmes avec les ORM. Mais toujours est-il que j'ai commencé à creuser le concept, et à l'aide de la réflection, j'ai réussit à implémenter un début de solution, qui permet plusieurs choses, mais en autre de faire ceci:

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
16
17
18
 
class Bar extends aspect{
    public function publicBar(){
        return $this->privateFooAttr;
    }
}
 
 
class Foo extends aspectable{
    private $privateFooAttr = '789';
}
 
 
$bar = new Bar();
$foo = new Foo();
 
$foo->applyAspect($bar);
echo $foo->publicBar(); //789

Sauf que j'arrive à certains problème de complexité cyclomatique au moment où je dois analyser les callee de certaines méthodes magiques pour déterminer si le scope à accès ou pas à l'attribut ou la méthode demandé.

Bref, avez-vous déjà expérimenté l'implémentation des aspects en PHP ? (sans utiliser d'extentions PHP ésotériques)


Ps.: Je vous donnerais bien un peu de code, mais ce sont la 90 lignes beaucoup trop honteuses pour l'instant


Au cas ou les contraintes de l'implémentation seraient pertinentes, voici ce que j'ai comme tests unitaires:
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
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 
 
testExternalScopeAttributeAccessFromBaseClass
 [x] Aspect public attr are accessible
 [x] Aspect private attr are not accessible
 [x] Aspect protected attr are not accessible
 [x] Base public attr are accessible
 [x] Base private attr are not accessible
 [x] Base protected attr are not accessible
 
testExternalScopeMethodAccessFromBaseClass
 [x] Aspect public method are accessible
 [x] Aspect private method are not accessible
 [x] Aspect protected method are not accessible
 [x] Base public method are accessible
 [x] Base private method are not accessible
 [x] Base protected method are not accessible
 
testInternalScopeAttributeAccess
 [x] Base class can access aspect public attr
 [x] Base class cannot access aspect protected attr <- *1
 [x] Base class cannot access aspect private attr <- *1
 [x] Aspect can access base class public attr
 [x] Aspect can access base class protected attr
 [x] Aspect cannot access base class private attr <- *2
 
testInternalScopeMethodAccess
 [x] Base class can access aspect public method
 [x] Base class cannot access aspect protected method <- *1
 [x] Base class cannot access aspect private method <- *1
 [x] Aspect can access base class public method
 [x] Aspect can access base class protected method
 [x] Aspect cannot access base class private method <- *2
*1) Pour le moment, je ne trouve pas de facon simple de valider si la requête est interne à la baseClass ou à un de ses aspects, ou si elle est externe, donc je dois me résigner à tout refuser.

*2) Il s'agit simplement d'un choix d'implémentation.


À noter que je n'ai pas encore rédigé mes tests pour m'assurer que l'instance $bar ne donne pas accès aux contenu privé de $foo... Je sais d'avance que j'aurais le même problème qu'en #1.