Page 1 sur 1

eval...

Posté : 25 juil. 2009, 17:16
par FuZZyLine
Salut les gens,

Voila, je dois lancer une fonction d'une class (inconnue de base) dont l'identité n'apparait qu'en variable utilisateur et de type abstraite. Présentement j'utilise un eval() (ca marche biensur)
mais je me demande si, justement, il n'y aurait pas une autre méthode qui soit moins
gourmande en ressource et plus joli... Je dois avouer que ce code avec toutes ces $values
c'est assez moche ;).

class MyClass extends ...
{
   .
   .
   .

   /**
    * @function : boolean dispatch(void)
    *
    * @param : none
    * @return : bool
    *
    * @comment : none
    */
    public function dispatch()
    {
      /**
       * Test et attribution selon résultat
       */
       if (!isset($this -> _urlEnvironment[url])) $url = "index";
       else $url = $this -> _urlEnvironment[url];

      /**
       * @string, nom du fichier
       */
       $fileName  = $url."xxx.php";

       if (!file_exists("./xxx/xxx/".$fileName)) exit(-1);

       require_once("./xxx/xxx/".$fileName);

      /**
       * @string, nom de la class
       */
       $className = ucfirst($url)."xxx";

      /**
       * @string, nom de la fonction
       */
       $fct = $url."Action";
       eval($className."::".$fct."();");

       return true;
    }
}
Si l'un de vous a une idée, merci d'avance.

A bientôt et bon code @+ ;)

Posté : 25 juil. 2009, 17:27
par fab
Il y très souvent ( toujours ? ) une meilleure soution qu'eval :)

http://fr.php.net/call_user_func

:p

Posté : 25 juil. 2009, 17:37
par FuZZyLine
Salut fab,
Il y très souvent ( toujours ? ) une meilleure soution qu'eval :)
http://fr.php.net/call_user_func
:p
Rah... Exact, quel idiot je suis ! Désolé j'aurai du y penser.

/me se fiche des claques !

Effectivement tu as tout à fait raison.

@+ et merci ;)

Posté : 25 juil. 2009, 17:47
par fab
C'est rien lol :)

Par contre oublie pas le résolu :)

PS: Petite note, si tu dois faire des appels en static c'est la meilleure solution sinon :
<?php
Class myClass {
    public function __construct() 
    {
        echo "Bonjour Mere-T \n";
    }

    public function test() 
    {
        echo "ceci est un test";
    }
}

$maClass = "myClass";
$monInstance = new $maClass;
$monInstance->test();


Posté : 25 juil. 2009, 18:09
par FuZZyLine
C'est rien lol :)
Mais si, j'insiste lol...

En revanche (et ca doit être pour ca que j'avais "claquemuré cette fonction)
Quand je lance la fonction dans MyClass, la class éxécutée n'a aucune idée du $this...
J'essai d'être plus clair, désolé.
class MyClass
{
   function dispatch()
   {
      .
      .
      .
      call_user_fun(Array($class, $fnct))
      // call_user_fun($class.'::MyFunction')

   }
}

class secondMyClass extends MyClass
{
   function xxx()
   {
      $this -> exemple = "Toto";
   }
}
La réponse du serveur est: Fatal error: Using $this when not in object context in ...

En revanche quand je commente la 1ere et décommente la seconde j'ai droit à :
...First argument is expected to be a valid callback...

Pour info je suis en php 5.2.6 donc : no soucis... Bizarre.

Afin d'être (encore plus clair) Le but que je recherche est que la fonction_class appellée soit appellée de façon abstraite et qu'en tant que fille elle puisse agir sur les variables de
la class parente.

Oups, j'essaie de simplifier mais je complique je crois ;(
Par contre oublie pas le résolu :)

PS: Petite note, si tu dois faire des appels en static c'est la meilleure solution sinon :
<?php
Class myClass {
    public function __construct() 
    {
        echo "Bonjour Mere-T \n";
    }

    public function test() 
    {
        echo "ceci est un test";
    }
}

$maClass = "myClass";
$monInstance = new $maClass;
$monInstance->test();
[/quote]
Je reviens un peu plus tard... 
Si je trouve en attendant je post la solution et clos le sujet, a bientôt @+ ;)

EDIT: forward_static_call me semble être la fonction qui correspondrait le mieux à mon attente
mais >= PHP 5.3. Autrement dit impossible à utiliser de mon côté. Je re-cherche lol

Posté : 25 juil. 2009, 18:20
par fab
Pour que ça marche correctement de mémoire c'est
call_user_func(array($class,$method)[,$args]);
Les arguments étant optionnels et non limité en nombre la syntaxe étant : $args,$args2,$arg3.

Mais si tu veux utiliser $this tu dois initialiser une instance de ta classe donc "new" et mon deuxième morceau de code, sinon tu fais des appels "static"

Posté : 25 juil. 2009, 18:36
par FuZZyLine
Pour que ça marche correctement de mémoire c'est
call_user_func(array($class,$method)[,$args]);
Les arguments étant optionnels et non limité en nombre la syntaxe étant : $args,$args2,$arg3.
Mais si tu veux utiliser $this tu dois initialiser une instance de ta classe donc "new" et mon
deuxième morceau de code, sinon tu fais des appels "static"
Exact, je te le confirme. Ta mémoire n'à pas de lacunes ;)
Mais mon soucis est que justement je souhaite que la class appellée le soit de manière abstraite,
static serait plus correcte, désolé. Bref, une fois la fonction éxécutée celle-ci est considérée
comme ayant été lancée hors class d'ou le soucis de ne pouvoir faire ce que je veux.

En gros et pour faire court hormis instanciée la class ne peut fonctionner...
Bien ennuyeux ca ;(

Je laisse ouvert le sujet 1 ou 2 heures puis le clos,

Merci à toi pour la piste ;)

EDIT:

Après quelques essais j'ai eu cette idée mais c'est hyper laid !
/**
 * MyClass.php 
 * .
 * .
 */
 class MyClass extends parent ParentMyClass ...
 {
   .
   .
   .
   public function dispatch()
    {
     /**
      * Test et attribution
      */
       if (!isset($this -> _urlEnvironment[url])) $url = "index";
       else $url = $this -> _urlEnvironment[url];

      /** 
       * Nom du fichier à include
       */
       $fileName  = $url."xxx.php";

     /**
      * Test puis chargement, sinon on sort
      */
      if (!file_exists("./xxx/xxx/".$fileName)) exit(-1);
      require_once("./xxx/xxx/".$fileName);

     /**
      * Nom de la class
      */
      $className = ucfirst($url)."xxx";
        
     /**
      * Nom de la fonction
      */
      $fct = $url."Action";

     /**
      * Appel de la fonction pointée par l'url...
      */
      call_user_func(Array($className, $fct), Array($this));

     /**
      * Simple point de test
      */
      print_r($this);

       return true;
    }
 }

/**
 * xxx.php extends MyClass
 * .
 * .
 */
 class xxx extends MyClass
 {
    function xxxAction($obj)
    {   
       $obj[0] -> title = "Dans la fonction : ".__FUNCTION__.", class : ".__CLASS__;
       return true;
    }
    .
    .
    .
 }
Ca marche parfaitement mais le HIC: c'est que c'est très très moche. L'idée est bien la mais
être obligé d'envoyer l'objet en argument je trouve ca stupide...
Tampis, une idée, en dormant, me viendra peut-être lol Au cas ou je garde encore ouvert ce topic
jusqu'à demain.

Bon code à tous @+ ;)

EDIT: (avant de clore)

Après avoir bien cherché, essayé divers possibilitées : Impossible de faire ce que je veux
sans passer par eval(), domage... Et comme il est hors de question d'utiliser "une bouffeuse de ressources" la solution qui se raproche le plus du résultat espéré est l'accès via Instance utilisant en extends une class de type abstract. Voili, Voilou...

Merci pour l'aide en tout cas, bon code à tous, @+ ;)