Comment fonctionnent les methodes before et after dans les frameworks

Par Wakser, il y a 13 ans


Bonjour,

je suis en cours de la création de mon propre Framework PHP. et là je voudrais vous demander une petite question.
Comment les Frameworks assez connus tel que Symfony ou CakePhp arrive t-ils à gérer les Before et After dans leurs controllers.

Je bricole actuellement avec le constructeur et le destructeur de la classe Mère (AppController). Mais je suis sur qu'il y a une astuce plus intelligente.

BootStraper

$newInstance = new $controller_name();
$newInstance->__set("controller",$controller_name);
$newInstance->__set("action",$action);
if($action){
    $newInstance->$action();
}else{
    $newInstance->index();
}

Classe Users

class UsersController extends AppController{
public function users(){
parent::__construct();
}
public function index(){
    echo "index";
}
public function nouveau(){
    echo "Nouveau";
}
}

Classe AppController

class AppController{
    public function __construct(){
        echo "Contructeur AppController";
    }
    public function __destruct(){
        echo "Destructeur AppController";   
    }   
}

_______________
à l'appel de Users/nouveau, le résultat est comme le suivant :
Contructeur AppController
Nouveau
Destructeur AppController

_________________
Merci d'avance

2 réponses

BenFarhat, il y a 13 ans

Du Lourd ta question et hyper intéréssante :) on passe à un autre niveau d'existence :) Cela dit, je ne vois pas ou sont tes before et after? les assimile tu a tes fonction construct et destruct? Bref pour ce qui est de Cakephp tout comme zend ou ruby ou n'importe quel cms, il existe plusieurs types de before et after Au niveau de ton controller tu devras implementer les fonctions suivant: - beforeFilter() - beforeRender() - beforeRedirect() - afterFilter() (donc ne pas oublier l'intégration du template qui sera appelé via le controller) AU niveau de ton model tu as d'autres before et after - beforeFind() - afterFind() - beforeSave() - afterSave() - beforeDelete() - afterDelete() - beforeValidate() - afterValidate() Juste une remarque, en regardant le code de cake, je pensais avoir un systeme de hook comme sur drupal ou wordpress mais non!! au niveau du Controller, cakephp n'utilises ni hook, ni le constructeur mais plutot un pattern observateur qui est en écoute et qui lance les methodes (citées) si elle existe (un truc du genre if(metho && method\_exists(this,method)..) [code] public function implementedEvents() { return array( 'Controller.initialize' => 'beforeFilter', 'Controller.beforeRender' => 'beforeRender', 'Controller.beforeRedirect' => array('callable' => 'beforeRedirect', 'passParams' => true), 'Controller.shutdown' => 'afterFilter' ); }[/code] au niveau de son Model, c'est la même chose, [code] public function implementedEvents() { return array( 'Model.beforeFind' => array('callable' => 'beforeFind', 'passParams' => true), 'Model.afterFind' => array('callable' => 'afterFind', 'passParams' => true), 'Model.beforeValidate' => array('callable' => 'beforeValidate', 'passParams' => true), 'Model.afterValidate' => array('callable' => 'afterValidate'), 'Model.beforeSave' => array('callable' => 'beforeSave', 'passParams' => true), 'Model.afterSave' => array('callable' => 'afterSave', 'passParams' => true), 'Model.beforeDelete' => array('callable' => 'beforeDelete', 'passParams' => true), 'Model.afterDelete' => array('callable' => 'afterDelete'), ); } [/code] Si tu veux le faire à la wordpress, (avoir tes hooks prédéfinis) tu peut intégrer ceci ([url=http://abhinavsingh.com/blog/2009/07/how-to-add-wordpress-like-add\_filter-hooks-in-your-php-framework/]Source[/url]) [code] /\* plugin directory \*/ $hook\_dir = "hooks/"; /\* get all plugin files \*/ $hook\_files = glob(hook_dir."*.php"); /* array saving all our hooks on the_content */ hooks['the\_content'] = array(); /\* add\_filter functionality \*/ function add\_filter(on, func) { global $hooks; array\_push(hooks[on], $func); } /\* include plugin files \*/ foreach(hook_files as hook\_file) { require\_once(hook_file); } /* implement the hooks */ foreach(hooks['the\_content'] as $hook) { $content = call\_user\_func(hook, content); } echo $content; [/code] Sinon je ne sais pas si tu peux pas tout simplement lancer tel que le fait cakephp les fonction dans leur emplacement respectif (les beforexxx dans le constructeur et les after dans le destructeur) [code]class AppController{ public function \_\_construct(url) { // je récupère l'url array_shift(url); $this->url = $url; echo "Contructeur AppController"; } public function callfunction(enfant) { // dans l'url je cherche la méthode tmp= $this->url[0]; // si elle est défini je l'execute if(method\_exists(enfant,tmp)) { $enfant->tmp(); } } public function __construct(){ this->\_\_beforeFilter(); echo "Contructeur AppController"; } public function \_\_destruct(){ $this->\_\_afterFilter(); echo "Destructeur AppController"; } public function \_\_beforeFilter(method, args) { if(method\_exists(this, method)) { return call\_user\_func\_array(array(this, method), $args); echo "beforeFilter trouvé"; } } public function \_\_afterFilter(method, args) { if(method\_exists(this, method)) { return call\_user\_func\_array(array(this, method), $args); echo "afterFilter trouvé"; } } }[/code] sinon à la place des \*\*return call\_user\_func\_array(array(this, method), $args);\*\* essayer avec \*\*return = this->{method}** SI tu as trouvé la solution, merci de la partager

Wakser, il y a 13 ans

Je te remercie BenFarhat pour ces explications. mais ce que je cherche exactement c'est le fire event, je sais pas si le observer patern est capable de la faire.

Si j'appelle une fonction X, une autre fonction X s'auto appelle aussi.
du coup ca me permettra de gerer mes before et after fonctions et aussi de gérer mes views (je voudrais charger les views de manière automatique).