Précédent   Forum des professionnels en informatique > PHP > Outils > Zend > Zend Framework > Zend_Db
Zend_Db Forum d'entraide pour le composant Zend_Db du Zend Framework (création de requêtes, abstraction, ORM etc.). Avant de poster -> FAQ Zend_Db.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 07/01/2011, 10h33   #1
Membre actif
 
Sébastien CHOMY
Inscription : juillet 2010
Messages : 118
Détails du profil
Informations personnelles :
Nom : Sébastien CHOMY
Âge : 39
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : juillet 2010
Messages : 118
Points : 184
Points : 184
Par défaut méthode findBy pour Zend_Db

Bonjour,

A l'instar de la méthode find() de Zend_Db_Table_Abstract qui recherche par clé primaire et comme il existe pour l'ORM Doctrine, j'ai voulu créer via la méthode magique __call une méthode findByNameColumn($args), qui permettrait de rechercher par nom de colonne selon la ou les valeurs définies.

J'attends en retour un rowSet, mais c'est plutôt un NULL et je ne vois pas pourquoi ?

Voici le code
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
 
<?php
/**
 * abstract class extends Zend_Db_Table_Abstract
 * 
 * @name App_Db_Table_Abstract
 * @dir library/app/Db/Table
 * @package App
 * @author Sébastien CHOMY
 * @abstract 
 */
abstract class App_Db_Table_Abstract extends Zend_Db_Table_Abstract  
{
 
   /**
     * 
     * Fetches rows by name column.  
     * The second argument specifies one or more key value(s).
     * To find multiple rows by name column, the second argument must
     * be an array.
     * 
     * The findBy() method always returns a Rowset object, even if only one row
     * was found.
     * 
     * @param string $column name column
     * @param mixed (string | array ) $values argument where clause
     * @return Zend_Db_Table_Rowset_Abstract Row(s) matching the criteria.
     * @throws Zend_Db_Table_Exception
     */
    public function findBy($column, $values)
    {
        // Check if the provided column is a column of the table
        if (!isset($this->_metadata[$column])) {
            /**
             * @see Zend_Db_Table_Exception
             */
            require_once 'Zend/Db/Table/Exception.php';
 
            throw new Zend_Db_Table_Exception('Column "' . $column . '" not found in table.');
        }
 
 
        if (!is_array($values)) {
            $whereList[] = $values;
        } else {
            $whereList = $values;
        }
 
        if (!is_null($whereList[0])) {        
            $tableName = $this->_db->quoteTableAs($this->_name, null, true);
            $columnName = $this->_db->quoteIdentifier($column, true);
 
            $select = $this->select();
 
            foreach ($whereList as $keyPosition => $value) {
 
                $$value = $this->_db->quoteIdentifier($value);
 
                if ($keyPosition == 0) {
                    $select->where($this->_db->quoteInto($tableName . '.' . $columnName . ' = ?', $value));    
                } else {
                    $select->orWhere($this->_db->quoteInto($tableName . '.' . $columnName . ' = ?', $value));
                }
            }
        }
 
        // empty whereList should return empty rowset
         if (is_null($whereList[0])) {
            $rowsetClass = $this->getRowsetClass();
            if (!class_exists($rowsetClass)) {
                require_once 'Zend/Loader.php';
                Zend_Loader::loadClass($rowsetClass);
            }
            return new $rowsetClass(array('table' => $this, 'rowClass' => $this->getRowClass(), 'stored' => true));
        }
 
          return $this->fetchAll($select);
 
    }//end:: findBy
 
 
    /**
     * magic method
     */  
    public function __call($method, $args)
    {
 
        // call findBy() method
        $matches = array();
        if (preg_match('/^findBy(\w+?)$/', $method, $matches)) {
            // use inflector
            $inflector = new Zend_Filter_Inflector(':cible');
            $inflector->setRules (array( ':cible' => array('Word_CamelCaseToUnderscore', 'StringToLower') ));
            $column = $inflector->filter(array('cible' => $matches[1]));
            $this->findBy($column, $args[0]);
        }
 
    }//end::__call
 
}//Eof::class
?>
Et pour l'utiliser dans un controller

Code :
1
2
3
4
5
6
7
8
$rowSet = $MyDbTable->findByNameColumn($args);

$myDbTable doit être un objet de App_Db_Table_Abstract (code si dessus)

NameColumn à remplacer par un nom de colonne de votre table, toujours une majuscule pour le premier caractère et un majuscule pour chaque rupture, exemple : findByNameController pour la colonne name_controller

$args peut être une valeur ou array de valeur de type string.
__________________
Apprendre c'est se faciliter la vie !
http://e-tuto.fr
freeseb74 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/01/2011, 19h12   #2
Modérateur
 
Avatar de Nesmontou
 
Homme Benjamin PREVOT
Architecte de système d'information
Inscription : septembre 2004
Messages : 1 568
Détails du profil
Informations personnelles :
Nom : Homme Benjamin PREVOT
Âge : 30
Localisation : France, Nord (Nord Pas de Calais)

Informations professionnelles :
Activité : Architecte de système d'information
Secteur : Finance

Informations forums :
Inscription : septembre 2004
Messages : 1 568
Points : 2 493
Points : 2 493
Bonsoir,

Il ne manquerait pas un return dans ta fonction __call ?
Code :
return $this->findBy($column, $args[0]);
Non testé
__________________
Si vous ne pouvez expliquer un concept à un enfant de six ans, c'est que vous ne le comprenez pas complètement. Albert EINSTEIN

F.A.Q. : Java, PHP, (X)HTML / CSS

N'oubliez pas de cliquer sur le bouton Résolu en bas de page quand vous avez obtenu une solution à votre problème
Nesmontou est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/01/2011, 10h46   #3
Membre actif
 
Sébastien CHOMY
Inscription : juillet 2010
Messages : 118
Détails du profil
Informations personnelles :
Nom : Sébastien CHOMY
Âge : 39
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : juillet 2010
Messages : 118
Points : 184
Points : 184
Bonjour Nesmontou,

En plein dans le mille, BRAVO !
J'ai rajouté le return et il m'a retourné la classe rowset définit pour ma table.

Il faut que je creuse encore, car il me retourne bien la classe rowset définit pour mon modèle de table, mais il cherche la méthode delete dans le cas ci-dessous.

Il faut que je puisse utiliser la méthode Zend_Db_Table_Abstract::delete sur mon Zend_Db_Table_Rowset qui n'a pas de méthode delete.

Fatal error: Call to undefined method App_Db_Table_Rowset::delete()

Code :
1
2
3
 
	$rowSet = $this->TCoreModule->findByNameModule($args);
	if (!is_null($rowSet)) { $rowSet->delete(); }
Merci encore
__________________
Apprendre c'est se faciliter la vie !
http://e-tuto.fr
freeseb74 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/01/2011, 22h08   #4
Membre confirmé
 
Patrick Barroca
Inscription : mai 2008
Messages : 178
Détails du profil
Informations personnelles :
Nom : Patrick Barroca

Informations forums :
Inscription : mai 2008
Messages : 178
Points : 204
Points : 204
Hello,

pour ton delete il devrait suffire de foreach sur ton rowset et de demander à chaque row de se deleter en definissant App_Db_Table_Rowset::delete() si ton objet rowset étend le rowset zend.
Code :
1
2
3
4
5
 public function delete() {
  foreach ($this as $row) {
    $row->delete();
  } 
}
patbator est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/01/2011, 18h50   #5
Membre actif
 
Sébastien CHOMY
Inscription : juillet 2010
Messages : 118
Détails du profil
Informations personnelles :
Nom : Sébastien CHOMY
Âge : 39
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : juillet 2010
Messages : 118
Points : 184
Points : 184
Merci patbator,

Ta suggestion fut bonne, cela a fonctionné du premier coup.
Je vais encore faire des tests et donner un résumé sur cette méthode findBy.... qui peut s'avérer très utile.

merci encore à tous.
__________________
Apprendre c'est se faciliter la vie !
http://e-tuto.fr
freeseb74 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 17h35.


 
 
 
 
Partenaires

Hébergement Web