Bonjour,
Je possède une version électronique du PHP|Architect's Guide to PHP Design Patterns dont je me suis inspiré pour mettre au point un système de contrôleur frontal :
Mon contrôleur frontal met en place dans son constructeur une série de filtres que je parcours avec un objet itérator :
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
34
35
36
37
38
39
40 if( ! class_exists( 'Front_Controller' ) ) { final class Front_Controller { private static $o_Instance; private $o_FFI; private function __construct() { $this->o_FFI = new Front_FilterIterator; $this->o_FFI->RegisterFilter( new Front_FilterError ) ->RegisterFilter( new Front_FilterException ) ->RegisterFilter( new Front_FilterSession ) ->RegisterFilter( new Front_FilterOutput ); } public static function GetInstance() { if( ! self::$o_Instance instanceof self ) self::$o_Instance = new self; return self::$o_Instance; } public function Execute() { foreach( $this->o_FFI->Increment() as $o_Filter ) { $o_Filter->PreProcess(); } Front_Dispatcher::GetInstance()->Execute(); foreach( $this->o_FFI->Decrement() as $o_Filter ) { $o_Filter->PostProcess(); } } } }
Tous les filtres possèdent une interface commune :
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 if( ! class_exists( 'Front_FilterIterator' ) ) { final class Front_FilterIterator implements Iterator { private $i_Position, $b_Increment, $a_Filters; public function __construct() { $this->a_Filters = array(); $this->Increment(); $this->Rewind(); } public function & RegisterFilter( Front_FilterInterface $o_Filter ) { $this->a_Filters[] = $o_Filter; return $this; } public function & RemoveFilter( Front_FilterInterface $o_Filter ) { foreach( $this as $i_Key => $o_Value ) { if( get_class( $o_Filter ) == get_class( $o_Value ) ) unset( $this->a_Filters[$i_Key] ); } return $this; } public function & Increment() { $this->b_Increment = true; return $this; } public function & Decrement() { $this->b_Increment = false; return $this; } public function rewind() { $this->i_Position = ( $this->b_Increment )? 0 : count( $this->a_Filters ) - 1; } public function next() { $this->i_Position += ( $this->b_Increment )? 1 : -1; } public function key() { return $this->i_Position; } public function current() { return $this->a_Filters[$this->i_Position]; } public function valid() { return isset( $this->a_Filters[$this->i_Position] ); } } }
Dans mon fichier bootstrap (mon index.php) je démarre mon contrôleur frontal comme suit :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 if( ! interface_exists( 'Front_FilterInterface' ) ) { interface Front_FilterInterface { public function PreProcess(); public function PostProcess(); } }
[code]Front_Controller::GetInstance()->Execute();
Dans mon contrôleur frontal, j'ai ma fonction "Execute()" qui commence par exécuter la fonction "PreProcess()" sur tous mes filtres. Ensuite elle démarre le traitement de la requête client. Finalement elle exécute la fonction "PostProcess()" sur chacun de mes filtres mais à l'envers :
Ce qui a pour effet de me permettre la mise en place de tout un système de filtres me permettant d'effectuer différents contrôles comme par exemple un contrôle du buffer de sorties :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 public function Execute() { foreach( $this->o_FFI->Increment() as $o_Filter ) { $o_Filter->PreProcess(); } Front_Context::GetInstance()->Execute(); foreach( $this->o_FFI->Decrement() as $o_Filter ) { $o_Filter->PostProcess(); } }
Ce qui peut me permettre d'effectuer des tâches de maintenance comme par exemple la suppression des commentaires HTML (l'exemple est tiré du livre dont je vous ai parlé au début.
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 if( ! class_exists( 'Front_FilterOutput' ) ) { class Front_FilterOutput implements Front_FilterInterface { public function PreProcess() { ob_start(); } public function PostProcess() { echo ob_get_clean(); } } }
Que pensez-vous de cette méthode d'implémentation du pattern "Intercepting Filters" ? J'ai vu un peu partout sur le net que normalement il s'agissait d'une chaine de process, mais l'auteur du livre utilise cette méthode pour l'implémenter, c'est une sorte de chaine mais à double sens ...
Votre avis ?
Partager