Surcharge de méthode et format des arguments

Eléphant du PHP | 92 Messages

01 oct. 2010, 19:23

Bonjour,
Je voudrais créer une classe pour gérer des formulaires et qui pourrait être étendue assez facilement au niveau des types de champs gérés.
Je voudrais donc créer une classe principale et des classes supplémentaires par type de champ.
Par exemple :
class form{
}

class formInput{
    function __construct($label=false,$name,$value=false){
    }
}

class formButton{
    function __construct($label,$name,$action){
    }
}
Le but serait d'avoir une syntaxe spécifique par classe de champ, avec une méthode __tostring() qui affiche le code HTML correspondant.

Je voudrais pouvoir appeler mes champs aussi bien indépendamment que depuis la classe form :
$truc=new formInput('champ de test','test',false);
ou
$truc=new form();
$truc->input('champ de test','test',false);
Comme je ne veux pas définir des méthodes pour chaque champ dans la classe form (qui créeraient des instances des autres classes), je me suis intéressé à la surcharge de méthodes (__call) pour modifier ma classe form de cette façon :
class form{
    function __call($name,$arguments){
        $field_type='form'.$name;
        if(class_exists($field_type)) new $field_type($arguments);
    }
}
Ce qui ne marche pas, parce que les arguments traités par __call sont renvoyés sous forme de tableau.

Est-ce qu'il existe une fonction qui "transformerait" ce tableau d'arguments en n arguments que je pourrais passer à la classe appelée ?

ViPHP
xTG
ViPHP | 7331 Messages

01 oct. 2010, 20:27

Tu peux passer par un __construct() sans argument définis et les récupérer (et les vérifier) via la variable $argv.
Enfin à première vue c'est ainsi que je ferrai pour ma part.

Eléphant du PHP | 92 Messages

01 oct. 2010, 20:31

Tu peux passer par un __construct() sans argument définis et les récupérer (et les vérifier) via la variable $argv.
Enfin à première vue c'est ainsi que je ferrai pour ma part.
Oui mais justement, je voudrais garder mes __construct tels quels pour simplifier l'ajout de nouvelles classes.

Y a pas moyen de transférer les arguments interceptés par __call tels quels à la fonction exécutée (en l'occurrence, la méthode __construct d'une instance de classe), sans les ranger dans un tableau ?

ViPHP
ViPHP | 5462 Messages

01 oct. 2010, 21:18

faut faire avec call_user_func_array :wink:

Eléphant du PHP | 92 Messages

01 oct. 2010, 21:45

faut faire avec call_user_func_array :wink:
J'ai vu ça mais je ne comprends pas comment/si je peux l'utiliser dans mon cas. Tu aurais un exemple ?

ViPHP
ViPHP | 5462 Messages

01 oct. 2010, 22:10

faut faire avec call_user_func_array :wink:
J'ai vu ça mais je ne comprends pas comment/si je peux l'utiliser dans mon cas. Tu aurais un exemple ?
du coup non, avec __construct c'est pas possible va falloir faire autrement, en construisant sur un array tu peux mixer les 2

Eléphant du PHP | 92 Messages

01 oct. 2010, 22:46

en construisant sur un array tu peux mixer les 2
Comment ça ?

ViPHP
ViPHP | 5462 Messages

01 oct. 2010, 23:07

en construisant sur un array tu peux mixer les 2
Comment ça ?
genre comme ca :
class Test
{
    public function __construct($name, $label = '', $value = '')
    {
        if(is_array($name))
        {
            $this->name     = $name[0];
            $this->label     = $name[1];
            $this->value     = $name[2];
        }
        else
        {
            $this->name     = $name;
            $this->label     = $label;
            $this->value     = $value;
        }
    }    
}

Eléphant du PHP | 92 Messages

01 oct. 2010, 23:41

Mouais. :/

Je voulais éviter ce genre de chose, justement, en gardant du code le plus simple/minimaliste possible.

S'il n'y a pas d'autre solution, j'aime autant considérer des tableaux dans tous les cas, voire reposer sur une classe générique dont seraient dérivées les autres (c'est ce que je faisais jusqu'à présent mais je voulais simplifier mon code).

S'il n'y a pas moyen d'obtenir autre chose qu'un tableau d'arguments avec __call, je vais faire autrement.

ViPHP
ViPHP | 5462 Messages

01 oct. 2010, 23:50

Mouais. :/

Je voulais éviter ce genre de chose, justement, en gardant du code le plus simple/minimaliste possible.

S'il n'y a pas d'autre solution, j'aime autant considérer des tableaux dans tous les cas, voire reposer sur une classe générique dont seraient dérivées les autres (c'est ce que je faisais jusqu'à présent mais je voulais simplifier mon code).

S'il n'y a pas moyen d'obtenir autre chose qu'un tableau d'arguments avec __call, je vais faire autrement.
a toi de revoir le concept chaque champs est un type défèrent et doit contenir un name, le reste c'est des options, regarde ce qui se fait au niveau du ZF c'est a peu prêt dans le même esprit que toi

Mammouth du PHP | 1967 Messages

06 oct. 2010, 09:29

J'ai l'impression que je vois là une réponse à une question resté sans réponse (là)
J'imagine utiliser la fonction eval dans ce cas-ci
class form{
    function __call($name,$arguments){
        $field_type='form'.$name;
        $ligne_arguments = "'".explode("','",$arguments)."'";
        if(class_exists($field_type)) eval("new $field_type(".$liste_arguments.");");
    }
}
Reste à voir par rapport à l'utilisation de ton script si il n'y a pas de problème de sécurité.
Spols
pour les fan de rubik's cube ou pour les curieux ==> le portail francophone du rubik's cube

Eléphant du PHP | 92 Messages

06 oct. 2010, 12:14

Ah, je vais tester ça.
Finalement, j'étais parti sur un tableau pour construire mes classes de champs de formulaires, en passant le tableau $arguments de __call.