IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Fonction magique call


Sujet :

Langage PHP

  1. #1
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut Fonction magique call
    Bonjour,

    je me suis mis à Flex récemment et j'ai interfacé mon appli avec Zend_Amf afin de récupérer des données par php. J'ai bien réussi à effectuer cette connexion

    J'essaie maintenant de mettre en place un système de gestion d'authentification/autorisation avec Zend_Auth et Zend_Acl et j'ai également réussi. Je fais le test dans chaque fonction de ma classe associée à service avec la méthode if($acl->isAllowed...)

    Par contre j'ai un problème qui est le suivant (rien à voir avec flex ou Zend) : je cherche à créer une seule instruction qui vérifie les droits et non incorporer une instruction dans chaque méthode. J'ai pensé utiliser la méthode magique __call mais celle ci ne semble pas vouloir s'exécuter automatiquement avant l'appel de ma fonction à la différence de __contruct() .

    Un exemple pour illustrer

    Code php : 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
     
    class ServiceClasse {
     
       private $_validAuth = false;
     
       public function __construct() {
            $this->_validAuth = true;
       }
     
       public function __call($methode, $arguments) {
          //$this->_validAuth = true;
       }
     
       // Me retourne 'state3'
       public function getState() {
            if ($this->_validAuth == true)
                return 'state3';
            return 'state2';
       }
     
    }

    Code php : 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
     
    class ServiceClasse {
     
       private $_validAuth = false;
     
       public function __construct() {
            //$this->_validAuth = true;
       }
     
       public function __call($methode, $arguments) {
          $this->_validAuth = true;
       }
     
       // Me retourne 'state2'
       public function getState() {
            if ($this->_validAuth == true)
                return 'state3';
            return 'state2';
       }
     
    }

    je croyais que __call était lancé avant un appel de fonction mais apparemment non...?

    Merci

  2. #2
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    Avec un peu de retard je trouve ceci :

    __call() est lancé lorsque l'on invoque des méthodes inaccessibles dans le contexte de l'objet.
    Mais comment trouver ou faire via __contruct par exemple une méthode me retournant la fonction appelée (accessible) ?

    Merci

  3. #3
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    Bonjour,

    je reformule un peu mieux mon problème. En fait, j'appelle sous Flex un service php par cette instruction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <s:RemoteObject id="monService" destination="zend" showBusyCursor="true" source="ServiceClasse">
    	<s:method name="getState" result="changeState(event)"/>
    </s:RemoteObject>
    lequel service instancie ensuite une classe php. J'appelle une des méthodes php sous Flex comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    monService.getState()
    Je souhaite protéger ces appels derrière un système d'identification/autorisation via Zend_Auth et Zend_Acl ce que j'ai réussi. Cependant, je suis obligé pour le moment de tester l'autorisation dans chaque méthode via le prototype suivant :

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if($this->_acl->isAllowed($role, $class, $function))
    // on continue le traitement...

    Je souhaiterais pouvoir gérer une fois pour toute l'autorisation automatiquement mais je ne peux pas le faire dans le constructeur car je ne sais pas qu'elle fonction a été appelée directement de Flex.

    Pour le moment ma solution est la suivante :

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     
    private function verifDroits($methode){
        if($this->_acl->isAllowed($role, $class, $methode)) {
           return true;
        return false;
    }
     
    public function getState(){
         if($this->verifDroits('getState'))
             //........
     
    }

    Mais je me demande s'il n'y a pas encore plus simple...

  4. #4
    Invité
    Invité(e)
    Par défaut
    Sur Symfony, tu as la possibilité sur les classes controleurs de redéfinir une fonction preExecute() et postExecute(), ce qui correspondrait bien à ton besoin.

    Je n'ai pas le temps de me plonger en détail dans le code source du framework (tu peux y jetter un oeil de ton côté), donc je ne peux pas te dire exactement comme ça fonctionne, mais voici une idée que j'ai eu qui pourrait t'aider :

    En gros il te suffit de ne pas appeler directement tes méthode, mais de passer par une méthode générique

    (Code écris en live, je n'ai absolument pas testé )
    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
     
    abstract class genericAction {
     
           protected function preExecute() { }
           protected function postExecute() {}
     
           protected function execute($method)
           {
                $this->preExecute();
     
                // Récupère les arguments de la fonctionne, dépile le premier ( nom de la méthode à appeler )
                $args = func_get_args(); array_shift($args);
     
                // Appeler en callback la méthode demandée avec les arguments
                call_user_func_array(array($this, $method), func_get_args());
     
                $this->postExecute();
          }
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class monAction extends genericAction {
     
            public function preExecute() {
               // Gérer les droits ici
            }
     
            public function faireQuelqueChose() {
                // Proccess here
            }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    // Et pour l'utiliser
    $action = new monAction();
    $action->execute('faireQuelqueChose');
    Le problème qu'il va falloir résoudre avec ce snippet concerne le passage d'arguments entre la fonction execute et les actions du controleur, à toi de voir comment tu pourrais te débrouiller avec la fonction de callback call_user_func_array et la fonction func_get_args par ex ( j'ai tenté quelque chose mais je ne garanti rien ^^ )

    Une autre solution utilisant cette fois ci la méthode magique __call consisterait à donner un nom composé à tes action ( public function executeFaireQuelqueChose(), public function executeFaireAutreChose() ) puis à les appeler directement sans le préfixe :
    $monAction->faireQuelqueChose().
    A partir de ce moment, tu rentrera bien dans le __call(), à toi de gérer ensuite l'appel au preExecute() puis de rappeler manuellement la bonne méthode avec les bons arguments.
    Dernière modification par Invité ; 28/08/2010 à 10h57.

  5. #5
    Membre émérite Avatar de Madfrix
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    2 326
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juin 2007
    Messages : 2 326
    Points : 2 566
    Points
    2 566
    Par défaut
    Bonjour et merci de t'intéresser à mon problème.

    Je suis pas sur que le cas de figure que tu exposes m'aiderait car je peux exécuter une fonction avant ma fonction appelée de Flex par le constructeur notamment. Mon seul soucis est de pouvoir disposer du nom de la fonction appelée avant d'arriver dans l'exécution de ladite fonction afin d'effectuer mon traitement d'autorisation qui nécessite de connaitre le nom de la fonction (ressource).

    Mais maintenant que tu le dis, sous Zend, il y a aussi des helpers afin de connaitre le controleur, la fonction appelée etc...à creuser donc en effet

    EDIT: suite à ton edit, j'avais aussi pensé à faire quelque chose d'un peu tordu du style appeler une fonction qui n'existe pas avec comme argument ma fonction qui existe et ses arguments qui serait trappée par __call puis dispatchée vers la fonction mais je trouve ca un peu moyen comme code

Discussions similaires

  1. Fonction Open Call Hierarchy dans VS2005
    Par gleyral dans le forum Visual Studio
    Réponses: 1
    Dernier message: 09/12/2008, 09h47
  2. Réponses: 1
    Dernier message: 21/05/2007, 09h53
  3. [DOS] probléme d'utilisation de la fonction CALL
    Par Benjamin_es dans le forum Scripts/Batch
    Réponses: 3
    Dernier message: 19/03/2007, 16h01
  4. Réponses: 2
    Dernier message: 14/12/2006, 22h47
  5. Réponses: 3
    Dernier message: 05/11/2006, 13h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo