2013-01-01 16 views
9

Basta una semplice comprensione di alcune semplici query di database in ZF2. In ZF1 ho metodi semplici come questo:Zend Framework 2 Db Adapter Adapter set di risultati della query come ZF1

public function recordset() 
{ 
// listing of all records 
$db = Zend_Registry::get('db'); 
$sql = "SELECT " . $this->_selectlist() . 
    " from customer c"; 
$r = $db->fetchAll($sql); 
return $r; 
} 

In ZF2, come dovrei fare lo stesso? Ho provato quanto segue, ma questo restituisce solo quello che sembra un oggetto "Risultato", ma tutto quello che voglio è un array come ZF1 fatto con fetchAll. Se devo iterare l'oggetto risultato solo per fornire l'array in un secondo momento, che poi deve essere ripetuto più volte, sembra solo una duplicazione dello sforzo.

Comunque, ecco quello che ho in ZF2 finora:

//above the controller start I have: use Zend\Db\Adapter\Adapter as DbAdapter; 

public function blaAction() 
{ 
    $db = new DbAdapter(
     array(
      'driver'  => 'Pdo', 
      'dsn'   => 'mysql:dbname=mydb;host=localhost', 
      'username'  => 'root', 
      'password'  => '', 
      ) 
    ); 
    $sql = 'select * from customer'; 
    $stmt = $db->query($sql); 
    $results = $stmt->execute(); 
    $this->view->data = $results; 
    return $this->view; 
} 

In uscita, ottengo questo:

object(Zend\Db\Adapter\Driver\Pdo\Result)#197 (8) { 
    ["statementMode":protected]=> string(7) "forward" ["resource":protected]=> object(PDOStatement)#195 (1) { 
     ["queryString"]=> string(22) "select * from customer" 
    } ["options":protected]=> NULL ["currentComplete":protected]=> bool(false) ["currentData":protected]=> NULL ["position":protected]=> int(-1) ["generatedValue":protected]=> string(1) "0" ["rowCount":protected]=> NULL 
} 

Tuttavia, se cambio $ risultati per $results->count(); io anzi vedo un conteggio record. Come faccio ad arrivare ai dati come array? (un recordset completo)

A un certo punto ho visto qualcosa di simile: $results->current() Ma questo ha restituito solo un singolo record.

Solo una nota a margine. Vedo tutte le classi astratte della tabella che potrei usare, ma a questo punto del mio apprendimento, non voglio farlo. Voglio solo alcune semplici query su richiesta che restituiscano array come hanno fatto in ZF1. In ZF2, sembra esserci troppa "connessione" di cose in configurazioni e cose che sembrano eccessive. Ma, come framework, mi piace la flessibilità e l'app principale su cui sto lavorando in ZF1 potrebbe davvero beneficiare della modularità di ZF2. (altrimenti probabilmente andrei con altri framework)

Per favore perdonami la mia ignoranza, e grazie mille per qualsiasi aiuto!

+0

Lo come se fosse simile al mirror nativo di 'PDO', hai cercato un metodo come' fetchAll' su 'Zend \ Db \ Adapter \ Driver \ Pdo \ Result'? Altrimenti è necessario eseguire il ciclo su '$ result' come si farebbe con un PDOStatement eseguito, credo. – prodigitalson

+0

Sì, ho guardato i documenti: [link] http://framework.zend.com/apidoc/2.0/classes/Zend.Db.Adapter.Driver.Pdo.Result.html [/ link] Ma è solo mostrando 1 metodo che restituisce un array, che è "current()". E questo restituisce solo un singolo record. Peccato che non ci sia il metodo -> toArray() o simile. Non posso credere che non ci sia un modo per restituire un recordset in ZF2, senza l'uso delle loro classi di astrazione. – gregthegeek

+0

In genere a questo livello non vuoi un array ...vuoi il risultato effettivo come la risincronizzazione di mysqliresult o il PDOStatement perché lo stai scorrendo in loop. usare fetchAll di solito non è una buona abitudine anche se può essere conveniente in alcuni casi. probabilmente puoi fare '$ result-> getResource() -> fetchAll (PDO :: FETCH_ASSOC)' per aggirarlo. Anche se l'ID generale non consiglia mai Zend_Db in 2.x o 1.x ... Invece id va con Doctrine - DBAL se vuoi solo l'astrazione o l'ORM completo se lo vuoi. – prodigitalson

risposta

4

Ok, penso di aver capito. Almeno questo farà il lavoro per il momento. Fondamentalmente, è necessario aggiungere un ulteriore passaggio e alimentare l'oggetto risultato in un oggetto ResultSet che ha un metodo di convenienza toArray. Suppongo che questo potrebbe essere fatto in milioni di modi, ma ... funziona.

Tenete a mente, non lo farei in un controller, o anche in questo modo esatto, ma è solo un test a questo punto. Ci sono momenti in cui voglio che sia disponibile, ed è così che ZF2 può fare, se lo si desidera. (Mai badando buone cattive abitudini /)

Nella parte superiore del componente aggiuntivo Controller/utilizzare il ResultSet:

use Zend\Db\ResultSet\ResultSet; 

Ecco l'azione di prova di lavoro:

public function blaAction() 
{ 
    $db = new DbAdapter(
     array(
      'driver'  => 'Pdo', 
      'dsn'   => 'mysql:dbname=mydb;host=localhost', 
      'username'  => 'root', 
      'password'  => '', 
      ) 
    ); 
    $sql = 'select * from customer 
     where cust_nbr > ? and cust_nbr < ?'; 
    $sql_result = $db->createStatement($sql, array(125000, 125200))->execute(); 
    if($sql_result->count() > 0){ 
     $results = new ResultSet(); 
     $this->view->data = $results->initialize($sql_result)->toArray(); 
    } 
    return $this->view; 
} 

toArray è solo facendo un foreach loop per te, quindi, credo che continui ad aggiungere loop di array extra che volevo evitare, ma non avendo guardato la versione ZF1 del loro codice, forse sta facendo lo stesso comunque.

Quello che io probabilmente fare è creare una semplice classe db wrapper per Zend \ Db che sostituisce la mia dichiarazione Zend_Registry da ZF1 e aggiunge un metodo fetchAll e fetchOne, in questo modo posso rapidamente porta sopra un mucchio di codice ZF1 a ZF2 molto Più facile.

Grazie per il vostro contributo nei commenti, lo apprezzo.:)

Oh, volevo anche menzionare. Mi sono imbattuto in questo ponte classe qualcuno ha creato, che potrebbe anche essere utile: https://github.com/fballiano/zfbridge

EDIT: Così i risultati restituiti sono adattatori iterabile si scopre. Non sono sicuro di quali passi ho preso che hanno portato alla mia confusione, ma i risultati in $ db-> query vengono restituiti come oggetto Pdo \ Result e possono essere inseriti in foreach abbastanza facilmente. Ciò che mi ha incasinato è stato il fatto che, se var_dump, non mostra i dati dell'array, solo l'oggetto. Questo mi ha portato su un percorso totalmente confuso.

Ora, anche se quanto sopra funziona, questo è meglio IMO, perché possiamo prendere quell'oggetto, inviarlo dove vogliamo per l'iterazione in seguito. (piuttosto che ripetere l'intero ciclo per creare prima un array, solo per ripetere un altro ciclo, perdita di tempo in quel modo)

Ecco un esempio di lavoro che mi piace di più. fai un loop sull'oggetto e ci sono i tuoi dati! duh! Non sono sicuro di quanto mi manchi le cose semplici a volte. :)

public function blaAction() 
{ 
    $db = new DbAdapter(
     array(
      'driver'  => 'Pdo', 
      'dsn'   => 'mysql:dbname=gwdb;host=localhost', 
      'username'  => 'root', 
      'password'  => '', 
      ) 
    ); 
    $sql = 'select * from customer 
     where cust_nbr > ? and cust_nbr < ?'; 

    $rs = $db->query($sql)->execute(array(125000, 125200)); 
    // Source of confusion: this doesn't dump the array!!! 
    // It dumps the object properties for Pdo\Result 
    Debug::dump($rs); 
    // but it is still able to iterate records directly 
    // without toArray 
    foreach ($rs as $row){ 
     Debug::dump($row); 
    } 

    return $this->view; 
} 
8

Da http://framework.zend.com/manual/2.0/en/modules/zend.db.result-set.html:

Zend \ Db \ ResultSet è un sub-componente di Zend \ Db per astraendo l'iterazione di query rowset produzione.

in modo da poter effettuare le seguenti operazioni:

$statement = $db -> query($sql); 

/** @var $results Zend\Db\ResultSet\ResultSet */ 
$results = $statement -> execute(); 

$returnArray = array(); 
// iterate through the rows 
foreach ($results as $result) { 
    $returnArray[] = $result; 
} 

Ora è possibile inviare alla vista:

return new ViewModel(array('results' => $returnArray)); 
1

Il mio inglese è molto marcio
Ho anche riscontrato questo problema, $ returnType Definito in Zend \ Db \ ResultSet \ ResultSet
possiamo dare il terzo argomento per Zend \ Db \ Adapter \ Adapter, come questo

$adapter = new Zend\Db\Adapter\Adapter($db_config,null,new Zend\Db\ResultSet\ResultSet('array')); 
$re = $adapter->query('select * from mooncake', $adapter::QUERY_MODE_EXECUTE); 
$s = $re->current(); 
var_dump($s); 

ora, $ s è array

+0

un consiglio molto carino, lo terrò a mente! grazie! – gregthegeek

2

È possibile evitare il ciclo foreach effettuando le seguenti operazioni:

$statement = $db->query($sql); 

/** @var $results Zend\Db\ResultSet\ResultSet */ 
$results = $statement->execute(); 

$data = $result->getResource()->fetchAll(); 
// Now data is an array 
+0

Questo è il modo migliore, la migliore risposta. –

3

Dopo lunga ricerca ho Handel mia query SQL in ZF2 quel modo

Il trucco è la funzione PHP iterator_to_array