ZF2 将多行合并为 class 的 属性 应该是数组

ZF2 hydrating multiple rows into class's property that should be array

在 ZF2 中,假设我有这样一个来自数据库的查询结果:

Name | Value 
-----+-------
a    | 1
a    | 2
a    | 3
b    | 6
b    | 1
b    | 5
...

有个class:

class SomeClass 
{
    protected $values;
    // + getter and setter for $values
}

我想水合 SomeClass 以便我将 values 属性 作为数组,例如 [1, 2, 3].

如何做到这一点?

PS:我知道水合作用是用 HydratingResultSet() 完成的,但是据我所知,HydratingResultSet() 每 table 行水合一个物体,而在这里我需要水合作用1 个对象用于多行。

编辑:在@newage 发表评论后,了解到问题没有得到很好的描述。

我需要从 SomeClass 中实例化的对象,例如 a = new SomeClass()b = new SomeClass(),它们的 values 变量填充有 [1, 2, 3] a, and [6, 1, 5] for b -- 正好对应数据库查询结果中的 ab.

HydratingResultSet will return a ResultSet. ResultSet implements Iterator interface. It return array of results.

如果需要其他合集class,可以自己写。 例如:

$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter'); // Get an adapter
$hydrator = new ClassMethods; // Create a hydrator.
$entity = Entity\User::class; // Entity class name
$prototype = new EntityCollection($hydrator, $entity);
$table = new TableGateway('table_name', $dbAdapter, null, $prototype);

如果您的实体使用方法 set...get...,您需要使用 ClassMethods 水化器。如果实体具有属性,需要使用 ObjectProperty 水化器。

用于创建实体集合。需要创建一个集合 class,它需要实现 IteratorResultSetInterface

class EntityCollection implements Iterator, ResultSetInterface
{
    protected $entities = [];

    protected $hydrator;

    protected $entityName;

    public function __construct($hydrator, $entityName)
    {
        $this->hydrator = $hydrator;
        $this->entityName = $entityName;
    }

    public function initialize($dataSource)
    {
        foreach ($dataSource as $dataRow) {
            $this->append($this->hydrator->hydrate((array)$dataRow, new $this->entityName()));
        }
    }

    public function append($entity)
    {
        array_push($this->entities, $entity);
        return $this;
    }

    /* Need create all methods from Iterator */
    ...
}

UPDATE: after remark from @dima-dz. You can read all data from DB and use foreach.

像这样。例子

$someObjectA = new SomeClass();
$someObjectB = new SomeClass();
$result = $table->select([]);
foreach ($result as $row) {
    switch ($row->Name) {
        case 'a':
            $someObjectA->add($row->Value);
            break;
        case 'b':
            $someObjectB->add($row->Value);
            break;
    }
}

@newage,发布了一个很好的解决方案,但我发现还有另一种可能性可以做我想做的事,也许更简单一些。有一个 php 函数 parse_str() 可以解析来自 Mysql 字段的字符串并为 values 变量创建一个数组,如果你正确格式化 mysql 的内容场地。 mysql join 使用 ZF2 创建解析所需字符串的示例如下

->join(
    ['t' => 'Table', 
    't.Id = t1.Id',
    [
        'Values' =>
            new Expression("GROUP_CONCAT(
                 DISTINCT CONCAT_WS('=', t1.Id, t1.Name) SEPARATOR '&')"
            ),
    ]
)