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
-- 正好对应数据库查询结果中的 a
和 b
.
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,它需要实现 Iterator
和 ResultSetInterface
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 '&')"
),
]
)
在 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
-- 正好对应数据库查询结果中的 a
和 b
.
HydratingResultSet
will return aResultSet
.ResultSet
implementsIterator
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,它需要实现 Iterator
和 ResultSetInterface
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 '&')"
),
]
)