Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Salut à tous,
peut etre que ma question n'est pas ciblée à 100% sur le Zend_Framework, mais peut-être que l'utilisation du framework aura une décision finale sur la manière que je procèderai...
Est-il avantageux de nommer les champs d'un form du genre:
form[field1] , form[field2]
Avantage en PHP (Adapté en Zend):
Code :
$form = $this->_getParam('form');
//accès direct et rapide :
echo $form[field1] . "\n";
echo $form[field2] . "\n";
est-ce que cela est conseillé ou déconseillé?
est-ce que ca cause probleme en javascript?
est-ce une méthode qui s'intègre mieux avec les Zend_Filter_Input? comme en facilitant le mapping de mon tableau associatif $form passé à la routine de validation:
Code :
$validators = array(
'field1' => array(
'Alpha',
'presence' => 'required'
),
'field2' => array(
'Alnum',
presence => 'required'
),
....
$input = new Zend_Filter_Input($filters, $validators, $form, $options);
Bref, j'aimerais avoir vos opinions ou suggestions rapidement, afin de partir mon premier formulaire de mon systeme sur une base solide!
à tenir en compte: rapidité de développement, de validation totu en restant flexible le plus possible.... car je trouve un peu irritant de constament faire :
Code :
$field1 = $this->_getParam('field1');
$field2 = $this->_getParam('field2');
..........
$field_X = $this->_getParam('field_X');
merci à tous
Bruno
Hors ligne
Bonjour zonzon,
Perso je te déconseille cette approche parce que quand tu auras réellement des tableaux à gérer dans ton formulaire (un groupe de checkbox, des select à choix multiple, une liste de texte field dont tu ne connais pas le nombre,...), tu ne pourras pas récupérer un tableau.
par contre si $field1 = $this->_getParam('field1'); te saoule, tu peux faire :
$fieldList = $this->_getAllParams();
A+, Philippe
Hors ligne
que si que si tu peut très facilement récupérer tes tableaux
il arrive souvent dans un formulaire de véhiculer des informations qui concerne directement l'objet que l'on manipule et d'autre qui sont plutôt du contexte
par exemple un formulaire pour éditer un objet client et un champ hidden qui dit si c'est un nouveau client ou une mise à jour
dans ce cas il est pratique d'utiliser les nom comme
method
et pour les info client
client[name]
client[phone]
quant au check box pas de problème
client[checkgroup][valeur1]
client[checkgroup][valeur2]
etc.
du coup tu peux très bien récupérer ton client d'une seule opération
$client = $this->_getParam('client');
personellement je n'aime pas utiliser les tableau pour mes objets je fais donc
$client = (object)$this->_getParam('client');
ainsi $client est un objet que je peux manipuler sans difficulté
$client->name; $client->phone; foreach ($client->checkgroup as ckeckname => $value) { do(); }
je n'hésite pas nom plus à mettre plusieurs objets dans un formulaire
par exemple j'ai des clients qui on une adresse
mais j'ai aussi des partenaires qui ont une adresse et des fournisseur
un adresse est donc quelque chose d'indépendant d'un client donc dans mon formulaire client je mes les champs
client[name] client[firstname] etc et address[street] address[city]
ça facilite grandement la lecture du formulaire. et son traitement.
j'ai des collègues qui ont pris un convention
oClient sera un objet client alors que aClient sera un tableau
ainsi il ont écrit une methode qui récupère un élément du formulaire en fonction de sont type
$client = $this->_getParam('Client');
retournera un objet si oClient est dans les variables du formulaire
et retournera un tableau si aClient est présent
pour cela il suffit de surcharger _getParam()
mais on peut aller encore plus loin en fournissant un constructeur adapté pour ses objet métier
$client = $this->_getParam('Client', 'Myapp_Model_Client');
qui me retourne un objet de la classe Myapp_Model_Client
il ne me reste qu'à faire
$method= $this->_getParam('method'); $client = $this->_getParam('Client', 'Myapp_Model_Client'); if ($client->isValid()) { $client->save($method); }
Alors oui moi je dis fonce sur cette approche elle à pleins d'avantage.
par contre le code html du formulaire n'est pas exploitable avec d'autre langage que php par exemple c'est plus difficile de prendre le formulaire tel quel pour porter l'appli en java
il faut aussi penser à utiliser des id sur les input de ton formulaire. quand tu veux les manipuler en javascript. en effet sans id le name de l'input est suffisant pour le manipuler. mais en javascript client[name] est un tableau
par habitude je fai sainsi
<input id='client_name' type='text' name='client[name]' value='' />
ça permet d'avoir un ensemble cohérent et de ne pas mélanger les noms de variable de formulaire qui sont à destination du serveur des objets d'édition qui sont à destination du navigateur
A+JYT
Hors ligne
Bonjour sekaijin,
Dans le cas de tes checkbox, tu les déclare comment dans l'html ?
c'est un truc de ce genre ?
<input name="client[checkgroup][]" value="toto" type="checkbox"/>
A+, Philippe
Hors ligne
<input name="client[checkgroup][box1]" value="toto" type="checkbox"/>
ou
<input name="client[checkgroup][]" value="toto" type="checkbox"/>
dans le premier cas tu obtiends une hashtable les valeurs peuvent donc être identiques client[options][emailInfo]=1 et client[options][newsletter] = 1
dans le second un tableau indicé les valeur son nécessairement différentes
client[options][]=emailInfo et client[options][]=newsletter
il est possible d'imbriquer autant de niveau que l'on veut
<input name="client[person][name]" value="Sekaijin" type="text" /> <input name="client[person][firstname]" value="Jean-Yves" type="text" /> <input name="client[person][bird]" value="08/12/1948" type="text" /> <input name="client[address][street][number]" value="6" type="text" /> <select name="client[address][street][type]"> <option value="rue" selected="selected">rue</option> <option value="bd">boulevard</option> <option value="imp">impasse</option> </select> <input name="client[address][street][name]" value="Beethoven" type="text" /> <input name="client[address][postnnumber]" value="12130" type="text" /> <input name="client[address][city]" value="Sainte Affrique" type="text" /> <input name="client[options][emailInfo]" value="1" type="checkbox" checked="checked" /> <input name="client[options][newsletter]" value="1" type="checkbox" />
mais je n'aime pas trop multiplier ainsi les niveaux ça de rends que très rarement les choses plus simples
A+JYT
Dernière modification par sekaijin (31-08-2007 20:19:42)
Hors ligne
Bonjour à vous !
Voila, je suis tombé sur ce sujet concernant les formulaires, et je trouve la technique proposée par sekaijin très intéressante (comme souvent me direz vous ! ).
J'ai donc un formulaire d'enregistrement de client avec tous les champs du type "client[nom]".
Dans mon controller, j'arrive bien à récupérer tous les champs d'un coup, sous forme d'array ou d'objet standard. Mais la partie la plus intéressante me pose plus de problèmes :
J'ai une classe Client qui étend Zend_Db_Table, pour l'instant toute vide. J'y ai rajouté un constructeur avec les paramètres qui correspondent aux champs de mon formulaire
function __construct($civilite, $nom, $prenom, $adresse, $adresse2, $codePostal, $ville, $email, $telephone, $login, $password){ $this->civilite = $civilite; $this->nom = $nom; $this->prenom = $prenom; $this->adresse = $adresse; $this->adresse2 = $adresse2; $this->codePostal = $codePostal; $this->ville = $ville; $this->email = $email; $this->telephone = $telephone; $this->login = $login; $this->password = $password; }
et j'essaie d'instancier l'objet de la manière suivante :
Zend_Loader::loadClass('Client'); $client = $this->_getParam('client', 'Client');
Seulement ça ne fonctionne pas...
Je pense qu'il s'agit d'une erreur stupide, probablement liée à mon constructeur, mais je ne vois pas laquelle...
Pouvez-vous m'aider ?
Et encore une question : que se passe t'il pour les éléments de la table client qui ne sont pas spécifiés dans le constructeur (typiquement : l'id) ?
Merci d'avance pour vos réponses.
Hors ligne
je n'utilise pas cette façon de faire. pour moi les paramètre de formulaire restent un objet standard tant que je ne le donne pas au métier (il peut ainsi être mis en session par exemple)
la méthode _getParam ne prends pas en deuxième argument un nom de classe mais la valeur par défaut si le paramètre n'existe pas.
pour ma part j'ai un constructeur d'objet métier qui prends en paramètre soit un tableau soit un objet
et qui affecte les membres.
je peux donc lui passer en argument les données du formulaire.
abstract class Fast_Db_Row implements Fast_Collectionable_Interface { public $data = array(); public function __construct($object = null) { if (null != $object) { if ($object instanceof StdClass) { $object = get_object_vars($object); } elseif (is_array($object)&&($object['table'] instanceof Zend_Db_Table)) { $this->table = $object['table']; $object = $object['data']; } foreach ($object as $key=>$value) { $this->data[$key] = $value; } } } public function setTable($table) { $this->table = $table; } public function add() { if (!$this->table instanceof Zend_Db_Table) { Zend_Loader::loadClass('Fast_Exception_Db'); throw new Fast_Exception_Db(Fast_Exception_Db::INVALID_TABLE_OBJECT); } return $this->table->insert($this->data); } public function update() { if (!$this->table instanceof Zend_Db_Table) { Zend_Loader::loadClass('Fast_Exception_Db'); throw new Fast_Exception_Db(Fast_Exception_Db::INVALID_TABLE_OBJECT); } return $this->table->UpdateById($this->data); } public function toStdClass() { return (object) $this->data; } public function __get($key) { if (isset($this->data[$key])) { return $this->data[$key]; } else { Zend_Loader::loadClass('Fast_Exception_Db'); throw new Fast_Exception_Db(Fast_Exception_Db::UNDEFINED_KEY); } } }
mon objet métier dérive donc de ça il est conforme à un Zend_Db_Row hor mis son constructeur qui accepte des paramètre plus large.
du coup j'instancie une classe dérivé de celle-ci
class Adm_Model_User_Row extends Fast_Db_Row { public $data = array( 'usr_id' => null, 'usr_ident' => null, 'usr_pwd' => null, 'usr_name' => null, 'usr_firstname' => null, 'usr_mail' => '@orange-ftgroup.com'); }
et j'utilise cette classe pour lire des objet dans ma base
pour y placer un formulaire j'ai une méthode sur ma classe table
public function newRow($obj = null) { // voir $this->createRow(array) $row = new $this->_rowClass($obj); $row->setTable($this); return $row; }
je fais donc
$formData = $this->_getParam('user'); $data = $userTable->newRow($formData); $data->update();
A+JYT
Hors ligne
il y a aussi $this->_request->_get('param')
c'est celui que j'utilise le plus souvent car
ainsi quelque soit le type d'appel il fonctionne
GET POST mais aussi url comme http://locahost/controler/action/param1/value1/param2/value2 etc
A+JYT
Hors ligne
Ok, mais es ce que ça ne peut pas être considéré comme une faille de sécurité potentiel? Car quand je veux du post, je veux pas un param de l'url...
Mais il me semble qu'il existe un truc genre $this->_request->getPost('tavar'); Mais c'est quand même plus long que $_POST['tavar']....
Hors ligne
non car tu peux faire un isPost()
pour vérifier
Hors ligne
Okay! Je le note dans un coin de ma 'tit tête!
Merci.
Alala. Comment aurais-je pu douter du framework sur ce niveau...
Dernière modification par Mr.MoOx (23-11-2007 10:18:50)
Hors ligne
sekaijin a écrit:
non car tu peux faire un isPost()
pour vérifier
N'empêche que ca reste quand même plus long ... Quel est l'intérêt de passer par cette méthode plustôt que $_POST classique, il doit bien y en avoir un quand même
Hors ligne
de faire abstraction de la couche basse du language
les variable $_POST et autre ont déjà changé au fil du temps et des version le framwork lui définit une api qui s'adaptera si besoin au nouvelles version
et si demain tu gères le verbe PUT ou autre tu n'auras pas de variable $_PUT pour récupérer tes billes
ça rend l'interface http homogène c'est tout
à ce propos tu peux surcharger le Request de ZF pour l'améliorer tu peux par exemple faire du près traitement sur les données transmises et continuer à les récupérer de façon standard dans tes contrôleurs. c'est complètement transparent.
A+JYT
Hors ligne
Merci Sekaijin pour la réponse apportée. Je me suis apercu que je ne maitrisais pas assez le sujet, et en recoupant avec ce post, je commence à voir concretement ce qu'il faut que je fasse.
Merci de votre aide !
Edit: je viens de voir aussi le nouveau billet de ton blog, je suis préssé de le lire, dommage que je n'ai pas le temps ce matin !
Dernière modification par astec37 (27-11-2007 08:26:25)
Hors ligne
Sekaijin concernant ton input <input id='client_name' type='text' name='client[name]' value='' />
Y a t'il une raison particulière pour que ton id soit égale à 'client_name' et non à 'client[name]' ??
Y'a t'il un réel interet a les différencier ?
Dernière modification par Moimeme (27-11-2007 09:28:29)
Hors ligne
Moimeme a écrit:
Sekaijin concernant ton input
Code:
<input id='client_name' type='text' name='client[name]' value='' />Y a t'il une raison particulière pour que ton id soit égale à 'client_name' et non à 'client[name]' ??
Y'a t'il un réel interet a les différencier ?
oui l'id est à destination de javascript ou de css le name est à destination du formulaire
HTML prévois que si je champs n'a pas d'id comme le nom est unique on peut le manipuler en javascript par le name.
Je vous le déconseille fortement. Mettez TOUJOURS des id
utiliser client_mane ou tout autre id à la place de client[name] est une nécessite
client[name] est la valeur l'entrée valeur name de du tableau client en gros si name vaut 25 client[name] est la valeur de client[25] et si le tableau client n'existe pas tu as droits à un JS error de même si name n'existe pas
de plus même en prenant des précautions pour éviter ça (en utilisant systématiquement les ' ') il n'est jamais simple de manipuler de tels ids comment par exemple écrire
<label for='client_name'>Nom : <input id='client_name' type='text' name='client[name]' value='' /></label>
de façon générale le id ne doivent servir qu'au javascript et css les nom qu'au formulaire. donc on n'écrit pas
document.form.client[name]; //ce qui plante // mais document.getElementById('client_name'); // ce qui marche à coup sur
A+JYT
Hors ligne