Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Pages: 1
Bonjour,
Tout d'abord bravo à la communauté de Zend Framework pour le travail accompli, qui plus est en temps et en heure, et très bien documenté, ce qui est très appréciable pour un produit libre !
J'utilise Zend_db avec sa couche d'abstraction de données Zend_db_table, que je trouve pas mal du tout.
Mon problème est le suivant : j'interface les résultats obtenus par mes requete avec le framework dojo, qui propose des widgets de tableaux avec tri dynamique et mise à jour des données par import de données au format Json.
Avec l'export Zend_Json, pas de souci, les données extraites par un fetchall() de mon objet Zend_db_Table se transforment au format Json en un tournemain.
Le seul souci que je rencontre est que certains champs du tableau dojo portent des noms spécifiques, comme "id" par exemple (noms qu'on ne peut pas changer) ; or, il s'avère que dans les tables de ma base, j'utilise des noms plus explicites que "id", comme par exemple "toto_id" pour la table "toto".
Y aurait-il moyen élégant, lors d'un fetchAll (ou un fetchRow) 'standard' sur un objet Zend_db_table, d'assigner un autre nom aux colonnes, à la manière d'un 'AS' en SQL ? (par ex. 'SELECT toto_id AS id FROM toto')... Merci de ne pas citer de requête SQL, c'est précisément ce que je cherche à éviter ! ;-)
J'ai réellement envie d'utiliser cette couche que je trouve structurante, claire et pratique, mais je bute sur ce point et je n'ai pas pu trouver d'aide ni d'exemple dessus.
Merci par avance, en espérant ne pas être trop verbeux !
Dernière modification par manuv (26-07-2007 13:55:15)
Hors ligne
Bonjour et bienvenue !
Quand tu définis ta classe, tu peux définir ta propre classe de Row :
class MyTable extends Zend_Db_Table_Abstract { protected $_name = 'my_table'; protected $_rowClass = 'MyRow'; }
Ensuite dans ton Row tu peux surcharger _transformColumn :
class MyRow extends Zend_Db_Table_Row_Abstract { protected function _transformColumn($columnName) { $nativeColumnName = myTransformer($columnName); return $nativeColumnName; } }
Je ne l'ai pas utilisé moi même, je ne sais pas si ça marche... n'hésite pas à nous envoyer un code qui marche quand tu auras tordu le cou à ton problème
A+, Philippe
Hors ligne
Merci pour cette réponse rapide.
J'ai un peu honte, car c'était documenté sur la doc officielle Zend_framework...
Ceci dit, je n'y ai malheureusement rien compris (désolé).
Pour la rowclass, pas de souci. Pour la surcharge de la classe _transformColumn, pas de souci non plus. C'est après que les choses se compliquent. L'argument $columnName de la fonction myTransformer (codée par mes soins, c'est entendu) est de quelle nature ? S'agit-il du nom original ou du nom à donner à la colonne ?
Sur la doc officielle, ils mettent :
<?php class MyInflectedRow extends Zend_Db_Table_Row_Abstract { protected function _transformColumn($key) { $nativeKey = myCustomInflector($key); return $nativeKey; } } class Bugs extends Zend_Db_Table_Abstract { protected $_name = 'bugs'; protected $_rowClass = 'MyInflectedRow'; } $bugs = new Bugs(); $row = $bugs->fetchNew(); // Use camelcase column names, and rely on the // transformation function to change it into the // native representation. $row->bugDescription = 'New description'; ?>
A quoi correspond ce $row->bugDescription ?
Pas moyen de trouver un exemple concret sur Internet ...
Hors ligne
Bonjour,
Le bugDescription, tu peux laisser tomber, c'est leur table bugs qui doit contenir une colonne bugDescription.
Pour la fonction myTransformer($columnName), je suppose qu'elle prend en argument le nom de ta colonne dans ton Zend_Db_Table (donc une string) et renvoie le nom de la colonne dans la base mysql.
A+, Philippe
Hors ligne
Alors c'est bien ce que j'avais compris à l'origine...
Le souci, c'est qu'il me laisse les noms originaux des colonnes...
Je suis sous PostgreSQL avec un driver PDO. J'espère que ce n'est pas ça qui pose problème (je n'ai pas de base mysql sous la main pour tester).
Hors ligne
J'ai enfin compris l'intérêt de _transformColumn !
Et par la même occasion, j'ai compris pourquoi je n'obtenais aucun changement.
En fait, surcharger _transformColumn revient à permettre d'invoquer un résultat de requete pour une colonne donnée avec l'identifiant de son choix. Un exemple parlant :
J'ai une table toto avec un champ toto_id.
Je souhaiterais récupérer ce champ par la commande $row->id en lieu et place de $row->toto_id après un fetch.
Il me suffit de créer une rowclass dont la méthode _transformColumn($columName) possède la ligne suivante :
if ($columnName == 'id') return 'toto_id';
C'est bon à savoir, mais malheureusement cela ne répond toujours pas à ma question initiale...
En effet, j'invoque en PHP avec le nom de colonne que je souhaiterais obtenir en retour, mais entre temps _transformColumn me l'a converti avec le nom de colonne tel qu'il existe dans la base. Du coup, lorsque j'invoque Zend_Json::encode($rowset->toArray()); le ZF me renvoie les noms de colonne d'origine. Cela ne correspond donc pas à un 'AS' en SQL.
Merci en tout cas à Philippe, et si quelqu'un a une idée...
Hors ligne
J'ai un peu fouillé dans le code de Zend_Db_Table_Row_Abstract et Zend_Db_Table_Rowset_Abstract.
Le toArray() renvoie bien les noms de colonnes en base. par contre pour accéder à tes données, il faut bien faire
$row->id
et non $row->toto_id
Bref, le toArray ne prend pas en compte ton _transformColumn, mais les _get() et _set() le prennent bien en compte.
A priori rien n'est prévu dans le code pour faire un toArray() comme tu le souhaite.
Il y aurait moyen d'ajouter une fonction "toLogicalArray()" en sous-classant Zend_Db_Table_Row et Zend_Db_Table_Rowset, mais ça devient assez complexe.
Cela dit ton besoin me parait assez logique... c'est bizarre qu'ils aient fait le système à moitié...
A+, Philippe
Hors ligne
Tout à fait d'accord avec toi...
A leur décharge, Zend_framework est un produit encore jeune et a été développé en peu de temps !
Sur Hibernate, il existe en langage HQL une clause FROM qui effectue l'opération que je souhaite (si je ne me trompe pas)...
Je préfère ne pas modifier le Zend framework que j'utilise, de peur que les changements n'aillent pas dans mon sens. Je suppose que ce dont j'ai besoin fait partie des prochains ajouts !
Une autre approche serait d'ajouter une clause $from à mon fetchAll, mais apparemment, il n'est possible d'indiquer qu'une clause $where...
Ce qui est dommage, c'est que j'ai déjà commencé mon projet avec, et que j'ai désormais le choix entre le faire à la main ou attendre patiemment...
A moins que quelque chose m'ait échappé ?
Merci pour ton aide en tout cas.
Hors ligne
manuv a écrit:
...mais apparemment, il n'est possible d'indiquer qu'une clause $where...
On trouve des choses dans la doc avec de la patience
Hors ligne
En effet, j'ai fini par utiliser une méthode select DIRECTEMENT SUR LA CONNEXION PAR DEFAUT A LA BASE et arriver au résultat souhaité, mais ne pas perdre de vue qu'on perd ainsi à moitié l'intérêt des méthodes automatisées de la classe Zend_db_abstract, puisque nulle part on ne fait appel à l'objet créé...
Ce qui est étrange, c'est que la clause from existe pour une requete select "de base", alors qu'elle est absente pour une requete via l'objet Zend_db_abstract.
Donc, le résultat s'apparente un peu à de la bidouille (peut-être est-ce voulu ?), ce qui est dommage quand on considère la rigueur que peut apporter un framework.
Voilà voilà...
Hors ligne
Pages: 1