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 更改为,$results->count(); 我确实会看到记录数。我如何以数组的形式获取数据?(完整的记录集)

有一次我确实看到了类似的东西: $results->current() 但这只返回了一条记录。

只是一个旁注。我确实看到了我可以使用的所有表格抽象类,但是在我学习的这一点上,我不想这样做。我只想要一些简单的按需查询,它们可以像在 ZF1 中那样返回数组。在 ZF2 中,似乎有太多“连接”配置中的东西和看起来有点矫枉过正的东西。但是,作为一个框架,我喜欢灵活性,我在 ZF1 中开发的主要应用程序可以真正受益于 ZF2 的模块化。(否则我可能会使用其他框架)

请原谅我的无知,非常感谢您的帮助!

4

5 回答 5

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));
于 2013-01-07T04:05:54.277 回答
5

好的,我想我明白了。至少这暂时可以完成这项工作。基本上,您必须添加一个额外的步骤并将结果对象提供给具有 toArray 便利方法的 ResultSet 对象。我想这可以通过一百万种其他方式完成,但是……这行得通。

请记住,我不会在控制器中执行此操作,甚至不会以这种方式执行此操作,但此时它只是一个测试。有时我希望它可用,如果需要,这就是 ZF2可以做到的。(不管好坏习惯)

在控制器的顶部添加/使用 ResultSet:

use Zend\Db\ResultSet\ResultSet;

这是工作测试操作:

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 版本,也许它仍然在做同样的事情。

我可能会为 Zend\Db 创建一个简单的 db 包装类,它替换 ZF1 中的 Zend_Registry 语句并添加 fetchAll 和 fetchOne 方法,这样我可以更轻松地将一堆 ZF1 代码快速移植到 ZF2。

感谢您在评论中的投入,我很感激。:)

哦,我也想提一下。我遇到了某人创建的这个桥牌课程,这也可能会有所帮助: https ://github.com/fballiano/zfbridge

编辑: 所以返回的适配器结果是可迭代的。我不确定我采取了哪些步骤导致了我的困惑,但是 $db->query 中的结果作为 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;
} 
于 2013-01-02T08:18:55.410 回答
4

经过长时间的搜索,我以这种方式在 ZF2 中处理我的 SQL 查询

 $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

于 2015-07-16T07:19:30.363 回答
2

您可以通过执行以下操作来避免 foreach 循环:

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

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

$data = $result->getResource()->fetchAll();
// Now data is an array
于 2014-12-31T18:32:41.110 回答
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 是数组

于 2013-09-24T03:49:07.953 回答