Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Bonjour,
je dispose d'une table "aliment", avec un modèle qui utilise TableGateway. J'aimerai sélectionner toutes les valeurs de ma table aliment et les afficher dans ma vue.
Modèle AlimentTable.php :
<?php namespace Custom\Model; use Zend\Db\TableGateway\TableGateway; use Zend\Db\Adapter\Exception\InvalidQueryException; class AlimentTable { /** * @var TableGateway */ protected $tableGateway; public function __construct(TableGateway $tableGateway) { $this->tableGateway = $tableGateway; } public function getAdapter() { return $this->tableGateway->getAdapter(); } public function getAll() { $select = new \Zend\Db\Sql\Select(); $select->from($this->tableGateway->getTable()); return $select; } public function getAliment($id) { $id = (int)$id; $rowset = $this->tableGateway->select(array('id_aliment' => $id)); $row = $rowset->current(); if (!$row) { throw new \Exception("Could not find row $id"); } return $row; } public function saveAliment(Aliment $aliment) { $data = array( 'id_aliment' => $aliment->id_aliment, 'nom_aliment' => $aliment->nom_aliment, 'nom_categorie' => $aliment->nom_categorie, 'nom_sous_categorie' => $aliment->nom_sous_categorie, 'description' => $aliment->description, 'prix' => $aliment->prix, ); $id = (int)$aliment->id_aliment; if ($id == 0) { $this->tableGateway->insert($data); } elseif ($this->tableGateway->getAliment($id)) { $this->tableGateway->update( $data, array( 'id_aliment' => $id, ) ); } else { throw new \Exception('Form id does not exist'); } } public function deleteAliment($id) { $this->tableGateway->delete(array('id_aliment' => $id)); } }
CarteController.php :
<?php namespace Front\Controller; use Zend\View\Model\ViewModel; use Custom\Controller\CustomController; class CarteController extends CustomController { public function indexAction() { return new ViewModel( array( 'aliments' => $this->alimentTable->getAll(), //'cats' => $this->categorieTable->getAll(), //'subCats' => $this->sousCategorieTable->getAll(), ) ); } }
Lorsque je fais ceci dans ma vue index.phtml :
<?php print_r($aliments); ?>
j'ai l'affichage suivant :
Zend\Db\Sql\Select Object ( [specifications:protected] => Array ( [select] => Array ( [SELECT %1$s FROM %2$s] => Array ( [0] => Array ( [1] => %1$s [2] => %1$s AS %2$s [combinedby] => , ) [1] => ) [SELECT %1$s %2$s FROM %3$s] => Array ( [0] => [1] => Array ( [1] => %1$s [2] => %1$s AS %2$s [combinedby] => , ) [2] => ) ) [joins] => Array ( [%1$s] => Array ( [0] => Array ( [3] => %1$s JOIN %2$s ON %3$s [combinedby] => ) ) ) [where] => WHERE %1$s [group] => Array ( [GROUP BY %1$s] => Array ( [0] => Array ( [1] => %1$s [combinedby] => , ) ) ) [having] => HAVING %1$s [order] => Array ( [ORDER BY %1$s] => Array ( [0] => Array ( [1] => %1$s [2] => %1$s %2$s [combinedby] => , ) ) ) [limit] => LIMIT %1$s [offset] => OFFSET %1$s ) [tableReadOnly:protected] => [prefixColumnsWithTable:protected] => 1 [table:protected] => aliment [quantifier:protected] => [columns:protected] => Array ( [0] => * ) [joins:protected] => Array ( ) [where:protected] => Zend\Db\Sql\Where Object ( [unnest:protected] => [nextPredicateCombineOperator:protected] => [defaultCombination:protected] => AND [predicates:protected] => Array ( ) ) [order:protected] => Array ( ) [group:protected] => [having:protected] => Zend\Db\Sql\Having Object ( [unnest:protected] => [nextPredicateCombineOperator:protected] => [defaultCombination:protected] => AND [predicates:protected] => Array ( ) ) [limit:protected] => [offset:protected] => [processInfo:protected] => Array ( [paramPrefix] => [subselectCount] => 0 ) [instanceParameterIndex:protected] => Array ( ) )
donc à priori ma requête à fonctionné, mais pourquoi je ne vois pas mes valeurs de la BDD.
J'ai ensuite essayé ceci dans mon fichier index.phtml :
foreach($aliments as aliment) { print_r($aliment); }
La je n'obtiens rien du tout sur l'affichage.
Avez vous une idée? Merci.
Par la même occasion, est-il possible de faire un select avec un order avec TableGateway?
Hors ligne
Bonjour
Tout d'abord, avant de pouvoir accéder à ta fonction getAll() tu doit créé l'objet Aliment
(tu doit avoir une classe model Aliment qui définisse les propriété de tes aliments (nom, variétés, ...) avant AlimentTable.
$aliment = new Aliment(); $propriété_aliment = $aliment->get('déclarationAlimentTable')->getAll();
ensuite pour ta fonction getAll(), je te conseil d'utiliser celle déjà prévue : fetchAll().
(essai de te regarder la doc avec la création d l'Album, ça pourra t'aider )
Hors ligne
oui biensur je l'avais pas mise mais j'ai un modèle Aliment.php :
<?php namespace Custom\Model; use Zend\InputFilter\InputFilterAwareInterface; use Zend\InputFilter\InputFilter; use Zend\Db\Adapter\AdapterInterface; use Custom\Model\Entity; class Aliment extends Entity implements InputFilterAwareInterface { public $id_aliment; public $nom_aliment; public $nom_categorie; public $nom_sous_categorie; public $description; public $prix; public $creation; public $modification; protected $inputFilter; protected $dbAdapter; protected $columns = array( 'id_aliment', 'nom_aliment', 'nom_categorie', 'nom_sous_categorie', 'description', 'prix', 'creation', 'modification', ); public function setInputFilter(\Zend\InputFilter\InputFilterInterface $inputFilter) { $this->inputFilter = $inputFilter; } public function getInputFilter() { if (!$this->inputFilter) { $inputFilter = new InputFilter(); $this->inputFilter = $inputFilter; } return $this->inputFilter; } public function setDbAdapter(AdapterInterface $adapter) { $this->dbAdapter = $adapter; } public function getDbAdapter() { return $this->dbAdapter; } }
Ba la méthode getAll(), que je l'appelle "fetchAll" ou "getAll" ou "toto", ça n'a pas d'importance, c'est ce qu'il y a dans le corps de la fonction qui compte.
[EDIT]
Bon effectivement en mettant ceci :
public function fetchAll() { $select = $this->tableGateway->select(); return $select; }
j'obtiens bien tout les lignes de ma table "aliment". Je ne vois pas ce que ça change de le mettre dans getAll.
Par contre l'utilisation de order de marche toujours pas.
Dernière modification par romsVLM (20-02-2014 17:31:27)
Hors ligne
Disons que fetchAll() est une convention ^^
tu parle du order du résultat de ta requête?
si c'est bien ça je te conseille plûtot de faire une requete du style:
public function getAllOrder($champ_to_order){ ... $resultSet = $this->tableGateway->select(function (Select $select) use($champ_to_order){ $select->order($champ_order.' DESC'); }); ... }
si c'est pas de ça que tu parlais.. j'aurais besoin d'un peu plus de précisions xD
Hors ligne
Merci c'est bien cela et ça fonctionne.
Mais pourquoi tant de complication pour un simple Order
Hors ligne
MMmmmhhhh..
Enfait quand tu utilise le order tu est dans une construction de requête.
La ça te parait long par ce que tu a qu'un simple order, mais il y a déjà un paramètre de rajouté pour que tu puisse choisir le champ qui va te trier le résultat (on pourrait en rajouter un autre pour remplacer DESC X_X)
, puis avec cette syntaxe il est tout de suite plus facile d'étoffer ta recherche :
$resultSet = $this->tableGateway->select(function (Select $select) use($id_example, $champ_to_order){ $select->where(array('id_example' => $id_example, 'actif' => 1) ->and ->where->between('value_example', 1, 100) $select->order($champ_order.' DESC'); });
Hors ligne
Merci beaucoup.
Par contre je rencontre un autre problème, j'en profite pour poster ici.
J'ai une table "user" :
user_id
username
password
email
une table "user_role"
id
role_id
et une table "user_role_linker"
user_id
role_id
Certains utilisateurs se voient attribuer un role, donc une ligne leur est créée dans la table "user_role_linker"
Cependant certains utilisateurs n'ont pas de role (aucune ligne dans la table "user_role_linker").
J'aimerai faire une sélection de tous les utilisateurs qui n'ont pas de role affecté. Donc toutes les lignes de la table "user", dont user_id n'est pas présent dans la table "user_role_linker".
Mais je n'y arrive pas. j'arrive bien à sélectionner par exemple touts les utilisateurs qui ont le role "admin" :
$select = new \Zend\Db\Sql\Select(); $select->from($this->tableGateway->getTable()); $select->join('user_role_linker', 'user.user_id = user_role_linker.user_id'); $select->where(array('user_role_linker.role_id' => 2));
Mais ce n'est pas ce que je veux.
Avez vous une idée?
Merci
Hors ligne
hola hola
Honnêtement tu m'a posé une colle avec ta question la ^^
j'y avais encore jamais réfléchis (et pourtant ça à l'air si courant comme requête =o)
bon j'ai un petit truc pour t'aider, mais il est certains qu'il y a bien mieux pour faire ce que tu voudrais.
$resultSet = $this->tableGateway->select(function (Select $select) { $select->where->addPredicate(new \Zend\Db\Sql\Predicate\Expression('user_id NOT IN ( SELECT other_user_id FROM your_table)')); });
en gros la dedans on va utiliser les Expressions de Zend "\Zend\Db\Sql\Predicate\Expression" cela te permet d'écrire tes conditions directement,
pour avoir une meilleure syntaxe, tu devrais utiliser :
$select->where(array(new \Zend\Db\Sql\Predicate\NotIn('user_id', $subSelect)) // $subselect est un tableau de tes valeurs à éviter ou un autre select à traiter
mais pour ça j'ai pas vraiment d'exemple donc je te laisse chercher ^_^
voilou voilou,
bonne soirée
Hors ligne
Voici la solution pour ceux qui sont intéressés :
$select = new \Zend\Db\Sql\Select(); $select->from($this->tableGateway->getTable()); $select->join('user_role_linker', 'user.user_id = user_role_linker.user_id', array(), Select::JOIN_LEFT); $select->where('user_role_linker.user_id IS NULL');
ou encore
$select = new \Zend\Db\Sql\Select(); $select->from($this->tableGateway->getTable()); $select->join('user_role_linker', 'user.user_id = user_role_linker.user_id', array(), Select::JOIN_LEFT); $select->where('user.user_id NOT IN (SELECT user_role_linker.user_id FROM user_role_linker)');
sur plusieurs tables :
SELECT table1.* FROM table1 LEFT JOIN table2 ON table2.name=table1.name LEFT JOIN table3 ON table3.name=table1.name WHERE table2.name IS NULL AND table3.name IS NULL
Hors ligne