2013-05-16 12 views
5

Nella mia classe Mapper sto estendendo AbstractDbMapper da ZfcBase per recuperare le righe dal database. Un semplice esempio potrebbe essere il codice come questo:Converti Zend Db ResultSet HydratingResultSet in matrice di oggetti

class MyMapper extends AbstractDbMapper 
{ 

    //... 

    public function fetchAll() { 
     $select = $this->getSelect(); 
     return $this->select($select); // returns HydratingResultSet 
    } 
} 

Il problema è che $this->select() restituisce un Zend\Db\ResultSet\HydratingResultSet (contenente gli oggetti necessari e idrati). Ma mi piacerebbe restituire una matrice di questi oggetti invece di uno HydratingResultSet contenente gli oggetti.

La prima cosa da guardare sarebbe HydratingResultSet::toArray() ma restituisce una matrice multidimensionale invece di una matrice di oggetti.

così ho scelto di farlo a mano:

public function fetchAll() { 
     $select = $this->getSelect(); 

     $results = array(); 
     foreach ($this->select($select) as $object) { 
      $results[] = $object; 
     } 
     return $results; // returns array of needed objects 
} 

Questo funziona, ma sembra brutto in ogni metodo di recuperare. Devo modificare il codice da select() per ottenere il comportamento desiderato o esiste un modo più semplice?

Btw: Si consiglia di restituire un array o convertirlo in questo modo? Grazie per l'aiuto!

+0

C'è un motivo per cui è necessario un array? Il Resultset funzionerà perfettamente come un iteratore e può essere utilizzato nella maggior parte dei casi. Non esiste un metodo integrato per ottenere l'array senza fare ciò che si sta facendo ora, è possibile aggiungere il metodo nel proprio Mapper o semplicemente Hydrator come scorciatoia. – Andrew

+0

Sto usando questi risultati nel mio controller e penso che sarebbe più pulito lavorare con gli array invece di alcuni oggetti Zend \ Db. Non capisco perché hanno scelto di farlo in questo modo ... – lorey

+1

hanno scelto di farlo in questo modo perché si ottengono funzionalità aggiuntive, come il buffering del set di risultati ecc. Pensa se hai una collezione di 9 milioni di oggetti, la matrice diventerà ENORME e consumerà RAM, con questa raccolta gli oggetti sono fatti su richiesta uno alla volta, è molto più efficiente. – Andrew

risposta

3

Aggiornamento:

Esiste una possibilità di pulizia (con lemmi da https://stackoverflow.com/a/19266650/1275778). Adattato per il mio esempio dall'alto funziona così:

public function fetchAll() { 
    $select = $this->getSelect(); 
    $results = $this->select($select); 
    return \Zend\Stdlib\ArrayUtils::iteratorToArray($results); // returns desired array of objects 
} 

Se limousine post qui la sua risposta, sarò felice di accettare.

Vecchia risposta:

Dal momento che nessuno poteva rispondere alla mia domanda ho cercato di attuare l'opzione più pulito (per me): si estende AbstractDbMapper per aggiungere la funzionalità menzionato. Mi documento qui per chi cerca una soluzione:

MyAbstractDbMapper extends AbstractDbMapper 
{ 
    /** 
    * @param Select $select 
    * @param object|null $entityPrototype 
    * @param HydratorInterface|null $hydrator 
    * @return array 
    */ 
    protected function select(Select $select, $entityPrototype = null, 
     HydratorInterface $hydrator = null) 
    { 
     $resultSet = parent::select($select, $entityPrototype, $hydrator); 
     $results = array(); // Array of result objects 
     foreach ($resultSet as $object) { 
      $results[] = $object; 
     } 
     return $results; 
    } 
} 

select() in MyAbstractDbMapper ora restituisce un array di oggetti, invece di HydratingResultSet.

Poiché questo è in downvoted, qualcuno potrebbe spiegare perché?

+1

Esempio di spiegazione e codice migliore qui: http://stackoverflow.com/questions/18940759/how-to-return-an-array-of-objects-in-zend-framework-2?ra=1 –

+0

Grazie, Bill! Questo è quello che stavo cercando! Grande! – lorey

1

solito hai già la classe di oggetti in ogni caso in modo da casi basta popupate del vostro oggetto (classe):

public function fetchById($id) { 

    [...] 

    $resultSet = $this->getDbTable()->fetchAll($select); 
    $entries = array(); 

    foreach ($resultSet as $row) { 
     $entries[] = $this->populate($row); 
    } 

    return $entries; 
} 

e la funzione Popola potrebbe essere simile a questo:

private function populate($row) 
{ 
    $entry = new Application_Model_YourModel(); 

    $entry->setId($row->id); 

    [...] //set other object values 

    return $entry; 
} 

Questo restituirà una matrice di oggetti

+0

Gli oggetti nel mio ciclo sono già del tipo necessario poiché "HydratedResultSet' fornisce un iteratore per eseguire il loop sugli oggetti idratati. Quindi questi NON sono oggetti riga e sono già stati idratati in 'AbstractDbMapper'. Quindi non c'è bisogno di una funzione populate e non c'è bisogno di usare fetchAll come '$ this-> select()' sta recuperando i risultati. – lorey

+1

Ok. quale versione di zend stai usando? 'ToArray()' soddisfa i tuoi bisogni? http://tgaconnect.com/dox/zend/html/class_zend_1_1_db_1_1_result_set_1_1_hydrating_result_set.html#a658defb34762c8f40085aec87e16ba1a – simplyray

+0

Sto utilizzando ZF 2.2. No, toArray() restituisce un array multidimensionale e quindi non contiene alcun oggetto. – lorey