2013-01-01 5 views
9

Po prostu potrzebuję strony zrozumienie prostych zapytań do bazy danych w ZF2. W ZF1 mam proste metody takie jak to:Zend Framework 2 Db Adapter Zestaw zapytań do adaptera, taki jak 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; 
} 

W ZF2, jak mam zrobić to samo? Próbowałem następujące, ale po prostu zwraca to, co wygląda jak obiekt "Wynik", ale wszystko, czego chcę, to tablica taka jak ZF1 zrobione z fetchAll. Jeśli muszę iterować obiekt wynikowy tylko po to, aby później dostarczyć tablicę, która następnie musi zostać powtórzona, wydaje się, że jest to tylko powielenie wysiłku.

W każdym razie, oto co mam w ZF2 tej pory:

//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; 
} 

W wyjściu, otrzymuję ten:

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 
} 

Jednak jeśli zmienię $ wyniki do $results->count(); I rzeczywiście widzę liczba rekordów. Jak mogę dostać się do danych jako tablicy? (pełny zestaw rekordów)

W pewnym momencie zobaczyłem coś takiego: $results->current() Ale to tylko zwróciło pojedynczy rekord.

Tylko notatkę. Widzę wszystkie abstrakcyjne tabele, z których mógłbym skorzystać, ale w tym momencie mojej nauki nie chcę tego robić. Chcę tylko kilka prostych zapytań na żądanie, które zwracają tablice, tak jak w ZF1. W ZF2 wydaje się, że jest zbyt dużo "łączenia" rzeczy w konfiguracje i rzeczy, które wydają się być przesadą. Ale jako struktura podoba mi się elastyczność, a główna aplikacja, nad którą pracuję w ZF1, może naprawdę skorzystać z modułowości ZF2. (w przeciwnym razie prawdopodobnie pójdę z innym szkieletem)

Proszę wybaczyć mojej niewiedzy i bardzo dziękuję za pomoc!

+0

Lo oks jak to jest bliższe natywnego 'PDO' czy szukałeś metody' 'fetchAll' na' Zend \ Db \ Adapter \ Driver \ Pdo \ Result'? W przeciwnym razie musisz pętli nad '$ result', jak gdybyś z wykonanym PDOStatement wierzę. – prodigitalson

+0

Tak, obejrzałem dokumenty: [link] http://framework.zend.com/apidoc/2.0/classes/Zend.Db.Adapter.Driver.Pdo.Result.html [/ link] Ale to jedyne pokazano 1 metodę zwracającą tablicę, która jest "current()". A to tylko zwraca pojedynczy rekord. Szkoda, że ​​nie ma metody -> toArray() lub podobnej. Nie mogę uwierzyć, że nie ma sposobu na zwrócenie zestawu rekordów w ZF2, bez użycia klas abstrakcji. – gregthegeek

+0

Na tym poziomie zwykle nie chcesz tablicy ...chcesz rzeczywisty zestaw wyników, jak mysqliresult resrouce, lub PDOStatement, ponieważ będziesz go przepuszczać. używanie fetchAll zazwyczaj nie jest dobrym nawykiem, chociaż w niektórych przypadkach może być wygodne. prawdopodobnie możesz zrobić '$ result-> getResource() -> fetchAll (PDO :: FETCH_ASSOC)' aby ominąć to. Chociaż ogólny id nigdy nie zaleca Zend_Db ani w 2.x ani 1.x ... Zamiast id idą z Doctrine - DBAL, jeśli tylko chcesz abstrakcji lub pełnej ORM, jeśli chcesz. – prodigitalson

Odpowiedz

4

Ok, myślę, że go mam. Przynajmniej to na razie wykona robotę. Zasadniczo, musisz dodać jeden dodatkowy krok i podać obiekt wyniku do obiektu ResultSet, który ma wygodną metodę toArray. Przypuszczam, że można to zrobić na milion innych sposobów, ale ... to działa.

Należy pamiętać, że nie zrobiłbym tego w kontrolerze, ani nawet w ten sposób, ale jest to tylko test w tym momencie. Są chwile, kiedy chcę, aby to było dostępne, i tak może zrobić ZF2 , jeśli chce. (Nigdy nie pilnuje dobre/złe nawyki)

W górnej części dodatku Controller/używać wynikowego:

use Zend\Db\ResultSet\ResultSet; 

oto działanie testu pracy:

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 właśnie robi foreach Pętla dla ciebie, więc myślę, że wciąż dodaje dodatkowe pętle tablicowe, których chciałam uniknąć, ale nie patrząc na wersję ZF1 ich kodu, może i tak robi to samo.

Najprawdopodobniej utworzę prostą klasę db dla Zend \ Db, która zastąpi moją instrukcję Zend_Registry z ZF1 i doda metodę fetchAll i fetchOne, dzięki czemu mogę szybko przesłać kilka kodów ZF1 do ZF2 wiele łatwiej.

Dziękuję za Twój wkład w komentarzach, doceniam to.:)

Och, chciałem też wspomnieć. Wpadłem na ten mostu klasy ktoś stworzył, który może również być pomocne: https://github.com/fballiano/zfbridge

EDIT: więc wyniki są zwracane adapter iterable się okazuje. Nie jestem pewien, jakie kroki podjąłem, które doprowadziły mnie do pomyłki, ale wyniki w zapytaniu $ db-> są zwracane jako obiekt Pdo \ Result i mogą być łatwo zapętlone w foreach. To, co mnie zepsuło, to fakt, że jeśli go zmienisz, nie pokazuje danych tablicy, tylko obiekt. To doprowadziło mnie do całkowicie mylącej ścieżki.

Teraz, mimo że powyższe działa, jest to lepsze IMO, ponieważ możemy wziąć ten obiekt, wysłać go tam, gdzie chcemy do iteracji później. (zamiast pętli nad całą rzeczą utworzyć najpierw tablicę, tylko po to, aby przerwać kolejną pętlę, strata czasu w ten sposób)

Oto działający przykład, który mi się podoba. po prostu zapętlasz obiekt i są twoje dane! duh! Nie wiem, jak czasami tęsknię za prostymi rzeczami. :)

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

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

Zend \ Db \ ResultSet jest sub-komponent Zend \ DB abstracting iteracji zestawu zestaw wierszy produkujących zapytaniami.

Więc można wykonać następujące czynności:

$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; 
} 

Teraz możesz wysłać go do widzenia:

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

mój angielski jest bardzo zgniłe
ja również napotkał ten problem, $ returnType Zdefiniowane w Zend \ Db \ ResultSet \ ResultSet
możemy podać trzeci argument dla Zend \ Db \ Adapter \ Adapter, tak jak ten

$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); 

teraz, $ s jest tablica

+0

bardzo ładna rada, o tym pamiętać! dzięki! – gregthegeek

2

Można uniknąć pętli foreach, wykonując następujące czynności:

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

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

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

To jest najlepszy sposób, najlepsza odpowiedź. –

3

Po długich poszukiwaniach i Handel moje zapytania SQL w ZF2 ten sposób

$sql = new \Zend\Db\Sql\Sql($this->tableGateway->getAdapter()); 
    $select = $sql->select(); 
    $select->from('table'); 
    $select->columns(array('*')); 
    $select->join("join table", "table.id = join table.id", array("*"), "left"); 
    $statement = $sql->prepareStatementForSqlObject($select); 
    $results = $statement->execute(); 
    return iterator_to_array($results)); 

Sztuką jest funkcja PHP iterator_to_array