Reputation: 538
In ZF2, suppose I have a query result from the database like this:
Name | Value
-----+-------
a | 1
a | 2
a | 3
b | 6
b | 1
b | 5
...
There is a class:
class SomeClass
{
protected $values;
// + getter and setter for $values
}
I want to hydrate SomeClass
so that I have the values
property as an array, like [1, 2, 3].
How to do this?
PS: I know the hydration is done with the HydratingResultSet()
, but AFAIK, HydratingResultSet()
hydrates one object per table row, whereas here I need to hydrate 1 object for several rows.
EDIT: after remarks from @newage, understood that the question wasn't well described.
I need to have the objects, instantiated from SomeClass
, like a = new SomeClass()
and b = new SomeClass()
that will have the values
variables filled with [1, 2, 3]
for a
, and [6, 1, 5]
for b
-- exactly what corresponds to a
and b
from the database query result.
Upvotes: 0
Views: 388
Reputation: 538
@newage, posted a great solution, but I found out there's another possibility to do what I wanted, maybe a bit simpler. There's a php function parse_str()
that can parse a string from Mysql field and create an array for the values
variable if you properly format the content of the mysql field. An example of a mysql join
with the ZF2 that creates the needed string for parsing is like this
->join(
['t' => 'Table',
't.Id = t1.Id',
[
'Values' =>
new Expression("GROUP_CONCAT(
DISTINCT CONCAT_WS('=', t1.Id, t1.Name) SEPARATOR '&')"
),
]
)
Upvotes: 0
Reputation: 909
HydratingResultSet
will return aResultSet
.ResultSet
implementsIterator
interface. It return array of results.
If you need other collection class, you can write it. For example:
$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);
If your entity with methods set...
and get...
, you need use ClassMethods
hydrator. If entity with properties, need use ObjectProperty
hydrator.
For creating a collection of entities. Need create a collection class, it need implement Iterator
and 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
.
Like this. Example
$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;
}
}
Upvotes: 1