IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Zend_Db PHP Discussion :

méthode findBy pour Zend_Db


Sujet :

Zend_Db PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    118
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2010
    Messages : 118
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  2. #2
    Membre Expert
    Avatar de Nesmontou
    Homme Profil pro
    Architecte logiciel
    Inscrit en
    Septembre 2004
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Architecte logiciel
    Secteur : Finance

    Informations forums :
    Inscription : Septembre 2004
    Messages : 1 612
    Par défaut
    Bonsoir,

    Il ne manquerait pas un return dans ta fonction __call ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return $this->findBy($column, $args[0]);
    Non testé

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    118
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2010
    Messages : 118
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    	$rowSet = $this->TCoreModule->findByNameModule($args);
    	if (!is_null($rowSet)) { $rowSet->delete(); }
    Merci encore

  4. #4
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    178
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 178
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     public function delete() {
      foreach ($this as $row) {
        $row->delete();
      } 
    }

  5. #5
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    118
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2010
    Messages : 118
    Par défaut
    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.

Discussions similaires

  1. Réponses: 4
    Dernier message: 02/05/2006, 12h08
  2. Méthode simple pour faire clignoter une editbox
    Par mr.saucisse dans le forum MFC
    Réponses: 5
    Dernier message: 10/03/2006, 11h57
  3. Réponses: 4
    Dernier message: 05/06/2005, 14h05
  4. Méthode simple pour gérer les collisions
    Par Hyoga dans le forum OpenGL
    Réponses: 2
    Dernier message: 19/02/2005, 13h43
  5. méthode à utiliser pour annuaire
    Par psyco2604 dans le forum ASP
    Réponses: 2
    Dernier message: 01/06/2004, 15h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo