Вопрос по frameworks, zend-framework2, php, database – Zend Framework 2 Db \ Adapter \ Адаптер результатов запроса, например ZF1

9

Просто нужна рука, чтобы понять некоторые простые запросы к базе данных в ZF2. В 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;
}

В ZF2, как бы я сделал то же самое? Я попробовал следующее, но это просто возвращает то, что выглядит как "Результат" объект, но все, что я хочу, это массив, как ZF1 сделал с fetchAll. Если мне нужно итерировать объект результата только для того, чтобы потом предоставить массив, который затем нужно будет повторить снова, это просто кажется некоторым дублированием усилий.

Во всяком случае, здесьЧто я имею в ZF2 до сих пор:

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

В результате я получаю это:

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 
}

Однако, если я изменю результаты в $ на$results->count(); Я действительно вижу количество записей. Как мне получить данные, хотя в виде массива? (полный набор записей)

В какой-то момент я увидел что-то вроде:$results->current() Но это вернуло только одну запись.

Просто примечание. Я вижу все табличные абстрактные классы, которые могу использовать, но на этом этапе обучения я неЯ не хочу этого делать. Я просто хочу несколько простых запросов по запросу, которые возвращают массивы, как в ZF1. В ZF2 естькажется слишком много "проводка " вещей в конфигах и прочее, что кажется излишним. Но, как фреймворк, мне нравится гибкость, и основное приложение, над которым я работаю в ZF1, действительно может выиграть от модульности ZF2. (иначе ябуду наверное идти с другими рамками)

Пожалуйста, прости мое невежество, и большое спасибо за любую помощь!

Похоже, это близко отражает роднойPDO Вы искали метод, какfetchAll наZend\Db\Adapter\Driver\Pdo\Result? В противном случае вам нужно перебрать$result как вы бы с выполненным PDOStatement я верю. prodigitalson
Да, я посмотрел на документы: [ссылка]framework.zend.com/apidoc/2.0/classes/... Но это только показывает 1 метод, возвращающий массив, который "ток()", И это только возвращает одну запись. Жаль, что тамнет ->метод toArray () или аналогичный. Я могу'не верю, что нетt способ вернуть набор записей в ZF2 без использования их классов абстракции. gregthegeek
Обычно на этом уровне вам не нужен массив ... вам нужен реальный набор результатов, такой как mysqliresult resrouce или PDOStatement, потому что вы будете проходить через него. использование fetchAll обычно не очень хорошая привычка, хотя в некоторых случаях это может быть удобно. вы, вероятно, можете сделать$result->getResource()->fetchAll(PDO::FETCH_ASSOC) обойти это. Хотя общий идентификатор никогда не рекомендует Zend_Db ни в 2.x, ни в 1.x ... Вместо этого идентификатор идет с Doctrine - DBAL, если вы просто хотите абстракцию или полный ORM, если вы этого хотите. prodigitalson

Ваш Ответ

5   ответов
3

После долгого поиска я обработал свой SQL-запрос в ZF2 таким образом

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

Хитрость заключается в функции PHP iterator_to_array

4

Хорошо я думаюу меня это есть. По крайней мере, это сделает работу в настоящее время. По сути, вы должны добавить один дополнительный шаг и передать объект результата в объект ResultSet, который имеет вспомогательный метод toArray. Я полагаю, это можно сделать миллионами других способов, но ... это работает.

Имейте в виду, я бы несделать это в контроллере, или даже таким точным способом, но это только тест на данный момент. Там'S раз, когда я хочу это доступно, и вот как ZF2Можно сделай это, если хочешь. (не обращая внимания на хорошие / плохие привычки)

В верхней части контроллера добавьте / используйте ResultSet:

use Zend\Db\ResultSet\ResultSet;

Вот's рабочее тестовое действие:

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 просто делает цикл foreach для вас, так что, я думаю, он по-прежнему добавляет дополнительные циклы массивов, которых я хотел избежать, но не рассматривал версию их кода ZF1, возможно, он делает то же самое в любом случае.

Вероятно, я сделаю создание простого класса-оболочки db для Zend \ Db, который заменит мой оператор Zend_Registry из ZF1 и добавит методы fetchAll и fetchOne, так что я смогу намного быстрее перенести кучу кода ZF1 в ZF2.

Спасибо за ваш вклад в комментарии, я ценю это. :)

О, я тоже хотел упомянуть. Я столкнулся с этиммост класс, который кто-то создал, что также может быть полезно:https://github.com/fballiano/zfbridge

РЕДАКТИРОВАТЬ: Таким образом, возвращаемые результаты адаптера оказываются итеративными. Я не уверен, какие шаги я предпринял, чтобы привести меня в замешательство, но результаты в $ db->запрос возвращается как объект Pdo \ Result, и его можно легко зациклить в foreach. Что меня запутало, так это то, что если вы его var_dump, это неПоказать данные массива, только объект. Это привело меня к совершенно запутанному пути.

Теперь, несмотря на то, что вышеприведенное работает, это лучше IMO, потому что мы можем взять этот объект, отправить его туда, куда мы хотим, для последующей итерации. (вместо того, чтобы зацикливаться на всем этом, чтобы сначала создать массив, только для повторения другого цикла, трата времени таким образом)

Вот'Это рабочий пример, который мне нравится больше. Вы просто зацикливаете объект, и тамВаши данные! Дух! Не уверен, что иногда я скучаю по простым вещам. :)

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

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

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

$data = $result->getResource()->fetchAll();
// Now data is an array
Это лучший способ, лучший ответ. Drk_alien
1

Мой английский очень гнилой

Я также столкнулся с этой проблемой, $ returnType определен в Zend \ Db \ ResultSet \ ResultSet

мы можем дать третий аргумент для Zend \ Db \ Adapter \ Adapter, вот так

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

теперь $ s это массив

очень хороший совет, имейте это в виду! Спасибо! gregthegeek
8

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

Zend \ Db \ ResultSet является подкомпонентом Zend \ Db для абстрагирования итерации запросов на наборы строк.

Таким образом, вы можете сделать следующее:

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

Теперь вы можете отправить его на просмотр:

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

Похожие вопросы