Php events manager

Soyez le premier à donner votre avis sur cette source.

Vue 8 134 fois - Téléchargée 315 fois

Description

Cette application distribuée sous licence LGPL permet la programmation évènementielle en PHP5. Elle permet aussi de simplifier l'installation d'un système de plugins dans vos applications.

Explication rapide :
1. Créer un évènement.
2. Créer des hooks. Ce sont des fonctions qui seront appelées lors du déclenchement des évènements.
3. Déclencher l'évènement.

Il suffit de lire le code source pour comprendre le fonctionnement très simple de l'application.

Source / Exemple :


<?php

/*

    • PHP Events Manager
    • Version 1.2.1 (26/08/2007)
    • Auteur : Psykocrash (SERRAJ Younes)
    • PHP Events Manager. Programmation évènementielle en PHP5.
    • Copyright (C) 2007 SERRAJ Younes - Tous droits réservés.
    • Licence : http://www.gnu.org/licenses/lgpl.txt
    • Cette bibliothèque est un logiciel libre ; vous pouvez la redistribuer ou
    • la modifier suivant les termes de la Licence Générale Publique Limitée
    • GNU telle que publiée par la Free Software Foundation dans la version 2.1
    • de la License.
    • Cette bibliothèque est distribuée dans l?espoir qu?elle sera utile, mais
    • SANS AUCUNE GARANTIE : sans même la garantie implicite de
    • COMMERCIABILISABILITÉ ou d?ADÉQUATION À UN OBJECTIF PARTICULIER. Consultez
    • la Licence Générale Publique Limitée pour plus de détails.
    • ** Vous devriez avoir reçu une copie de la Licence Générale Publique Limitée
    • avec cette bibliothèque ; si ce n?est pas le cas, écrivez à la :
    • Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
    • MA 02111-1307, USA.
  • /
if (!defined('PEM_PHP5_')) { define('PEM_PHP5_', true); class PEM { protected static $events_list = array(); public static $safe_mode = false; /*
    • Cette fonction cré un évènement
    • sur lequel pourront être placés
    • des hooks.
  • /
public static function create_event($event_name) { $event_exists = self::event_exists($event_name); if (self::$safe_mode === true && $event_exists === true) throw new Exception("[Safe Mode] L'évènement ''" . htmlspecialchars($event_name) . "'' existe déjà."); if (!$event_exists) self::$events_list[$event_name] = array(); } /*
    • Cette fonction vérifie si un
    • d'évènement existe.
    • Return: true/false.
  • /
public static function event_exists($event_name) { if (!is_array(self::$events_list)) return false; if (array_key_exists($event_name, self::$events_list) === true) return true; else return false; } /*
    • Cette fonction déclanche un évènement.
  • /
public static function raise_event($event_name, $params = '') { if (!self::event_exists($event_name)) throw new Exception("L'évènement ''" . htmlspecialchars($event_name) . "'' n'existe pas."); foreach (self::$events_list[$event_name] as $function_name_to_call) { if (!function_exists($function_name_to_call)) throw new Exception("La fonction ''" . htmlspecialchars($function_name_to_call) . "'' n'existe pas."); if (is_array($params)) call_user_func_array($function_name_to_call, $params); else call_user_func($function_name_to_call, $params); } } /*
    • Cette fonction supprime un évènement
    • et tous les hooks liés.
  • /
public static function delete_event($event_name) { if (!self::event_exists($event_name)) { if (self::$safe_mode === true) throw new Exception("[Safe Mode] L'évènement ''" . htmlspecialchars($event_name) . "'' n'existe pas."); } else unset(self::$events_list[$event_name]); } /*
    • Cette fonction cré un hook sur
    • un évènement.
  • /
public static function create_hook($event_name, $function_name_to_call) { if (!function_exists($function_name_to_call)) throw new Exception("La fonction ''" . htmlspecialchars($function_name_to_call) . "'' n'existe pas."); if (!self::event_exists($event_name)) throw new Exception("L'évènement ''" . htmlspecialchars($event_name) . "'' n'existe pas."); $hook_exists = self::hook_exists($event_name, $function_name_to_call); if (self::$safe_mode === true && $hook_exists === true) throw new Exception("[Safe Mode] Le hook ''" . htmlspecialchars($event_name) . '->' . htmlspecialchars($function_name_to_call) . "'' existe déjà."); self::$events_list[$event_name][$function_name_to_call] = $function_name_to_call; } /*
    • Cette fonction vérifie si un
    • hook existe.
    • Return: true/false.
  • /
public static function hook_exists($event_name, $function_name_to_call) { if (!self::event_exists($event_name)) throw new Exception("L'évènement ''" . htmlspecialchars($event_name) . "'' n'existe pas."); if (array_key_exists($function_name_to_call, self::$events_list[$event_name]) === true) return true; else return false; } /*
    • Cette fonction supprime un hook
    • existant.
  • /
public static function delete_hook($event_name, $function_name_to_call) { if (!self::hook_exists($event_name, $function_name_to_call)) { if (self::$safe_mode === true) throw new Exception("Le hook ''" . htmlspecialchars($event_name) . '->' . htmlspecialchars($function_name_to_call) . "'' n'existe pas."); } else unset(self::$events_list[$event_name][$function_name_to_call]); } } } ?>

Conclusion :


J'ai choisis la catégorie Divers parce que je ne sais vraiment pas laquelle choisir.

Si vous avez des idées d'amélioration, n'hésitez pas. Dans son état naissant, cette application remplit déjà pleinement sa fonction, mais on peut toujours la développer ;)

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

ornythorink
Messages postés
8
Date d'inscription
mardi 23 décembre 2003
Statut
Membre
Dernière intervention
28 août 2007
-
le commentaire va être trivail mais enfin des commentaires et réactions constructives. Dans un sens je comprend l'erreur de compréhension du pattern Observer j'ai fais la même ;)
Bon courage
malalam
Messages postés
10844
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
17 -
Un état n'est pas forcément un entier. Un état c'est ce qu'est devenu le contexte après un évènement donné. C'est bien à ça que tu veux réagir ? A un évènement. Quand tu dis "n'importe où, n'importe quand, et sans raison" ce n'est pas de la programmation évènementielle : cela revient à...appeler une fonction. Et pour ça, pas besoin d'une classe du tout. Ce n'est pas n'improet où, ni n'importe quand, et certainement pas sans raison, sinon tu ne lierais pas tes évènements et tes crochets.
Si tu observes attentivement le...observer..Pattern, tu verras que c'est très exactement ce qu'il fait aussi.
Pourquoi les objets? Parce que cela remplace avantageusement tes fonctions : tu peux alors effectuer des actions bien plus complexes.

Tu n'as pas modifié tes comparaisons : tu devrais les typer. Outre que c'est plus rapide (mais bon, vu l'ordre de grandeur...) c'est surtout plus strict et correct. true et 1 sont identiques. Alors que === true est très différent de === 1. Cela peut avoir son importance, et dans ce sens, il est mieux de prendre l'habitude de coder ainsi.
Coté code encore, vu comment tu as codé ta classe et comment tu dois l'utiliser, tu aurais dû la rendre entièrement statique : toutes les propriétés, et toutes les méthodes. Il est totalement inutile d'instancier ta classe pour l'utiliser. A dire vrai, puisque tu veux ne pas l'utiliser dans un contexte très orienté POO, c'est même bien mieux de ne pas l'instancier.
psykocrash
Messages postés
244
Date d'inscription
vendredi 14 juin 2002
Statut
Membre
Dernière intervention
17 mars 2009
-
Ce que t'en dis m'intéresse, sinon j'aurais pas posté mon code ici ;)

Reprenons :

Les évènements ici ne dépendent pas d'un changement d'état comme le voudrait l'Observer design pattern, un évènement peux intervenir n'importe quand, n'importe où, et sans raison. Dans ces conditions, difficile d'associer un sujet, ainsi que ses états, à un observateur précis. Moi je veux bien utiliser ce design pattern, mais faudra m'expliquer comment faire dans cette configuration...

Sinon tu as parlé à plusieurs reprises de passer en paramètre des objets plutôt que des fonctions. Vu que le but est d'appeler des fonctions, je comprend pas pourquoi utiliser des objets ?
malalam
Messages postés
10844
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
17 -
L'observer pattern fait très exactement ce que ta classe fait. En implémentant une norme histoire de s'y retrouver facilement. Tu lies un déclencheur à un évènement. Sauf que l'avantage est de pouvoir :
- utiliser un objet complexe comme "hook"
- de déclencher plusieurs actions en cascade : ce n'est pas tout à fait ce que tu as compris. Un évènement entraîne X actions. C'est possible avec ta classe mais pas simplement, et tu n'as aucune interaction possible avec ton environnement. Réagir à un changement est intéressant sans que tu aies à appeler MANUELLEMENT ta fonction. Ta classe ne fonctionne pas comme un trigger. Ou du moins, encore une fois, pas facilement.

Pour la SPL, à jouer avec les itérateurs. Ton objet gagnerait à étendre ArrayIterator, si tu veux que je sois précis. Ou alors, une autre solution est celle que j'ai utilisée : ton event_list doit être un SPLObjectStorage, ce qui t'évite de définir tes méthodes create_event() et compagnie.

Mais bon..ce que j'en dis, moi :-)
psykocrash
Messages postés
244
Date d'inscription
vendredi 14 juin 2002
Statut
Membre
Dernière intervention
17 mars 2009
-
Merci pour tes remarques.

Je me suis renseigné à propos du design pattern Observer, et ce n'est pas du tout ce que je cherche à faire. De ce que j'ai compris, il y a les sujets, et les observateurs, mais tout ça se passe à l'intérieur d'un objet. Mon objectif avec mon application/méthode c'est de pouvoir placer des évènements partout dans mon code (dans la partie "globale"), pas de gérer des évènements au sein d'un objet.

Pour la SPL, j'ai jeté un oeil sur php.net, mais je t'avoue ne pas voir en quoi elle m'aiderait.

Pour le fait d'être limité à une seule fonction, si j'ai bien compris ce que tu voulais dire, et bien non. Pour chaque évènement, tu peux placer autant de hooks que tu le souhaites (hook ici = fonction à appeler). D'ailleurs j'ai une petite idée d'amélioration à ce sujet que je vais implémenter dans la prochaine version.

Pour les exceptions, tu as raison, je vais faire une mise à jour tout de suite.

D'autres remarques/suggestions ?

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.