1

I know we have result set to get a row as object But How can I get every field as a separate object ? consider of this database row :

user_id     address_id  product_id  shop_id
5               3       134          2

I want to retrieve and save the row as follows :

userEntity  AddressEntity   ProductEntity   ShopEntity
0

1 Answer 1

4

This is not how the TableDataGateway is supposed to be used, since what you are looking for are more complex features such as the ones of Doctrine 2 ORM and similar data-mappers.

Here is one possible solution to the problem, which involves using a custom hydrator (docs). My example is simplified, but I hope it clarifies how you are supposed to build your resultset.

First, define your entities (I'm simplifying the example assuming that UserEntity is the root of your hydration):

class UserEntity {
    /* fields public for simplicity of the example */
    public $address;
    public $product;
    public $shop;
}
class AddressEntity { /* add public fields here for simplicity */ }
class ProductEntity { /* add public fields here for simplicity */ }
class ShopEntity { /* add public fields here for simplicity */ }

Then, build hydrators specific for the single entities:

use Zend\Stdlib\Hydrator\HydratorInterface as Hydrator;

class AddressHydrator implements Hydrator {
    // @TODO: implementation up to you
}

class ProductHydrator implements Hydrator {
    // @TODO: implementation up to you
}

class ShopHydrator implements Hydrator {
    // @TODO: implementation up to you
}

Then we aggregate these hydrators into one that is specifically built to hydrate a UserEntity:

class UserHydrator extends \Zend\Stdlib\Hydrator\ObjectProperty {
    public function __construct(
        Hydrator $addressHydrator,
        Hydrator $productHydrator,
        Hydrator $shopHydrator
    ) {
        $this->addressHydrator = $addressHydrator;
        $this->productHydrator = $productHydrator;
        $this->shopHydrator    = $shopHydrator;
    }

    public function hydrate(array $data, $object)
    {
        if (isset($data['address_id'])) {
            $data['address'] = $this->addressHydrator->hydrate($data, new AddressEntity());
        }

        if (isset($data['product_id'])) {
            $data['product'] = $this->productHydrator->hydrate($data, new ProductEntity());
        }

        if (isset($data['shop_id'])) {
            $data['shop'] = $this->shopHydrator->hydrate($data, new ShopEntity());
        }

        return parent::hydrate($data, $object);
    }
}

Now you can use it to work with your resultset. Let's define the service for your UserEntityTableGateway:

 'UserEntityTableGateway' => function ($sm) {
     $dbAdapter          = $sm->get('Zend\Db\Adapter\Adapter');
     $resultSetPrototype = new ResultSet();

     $resultSetPrototype->setArrayObjectPrototype(new UserHydrator());

     return new TableGateway('user', $dbAdapter, null, $resultSetPrototype);
 },

These are all simplified examples, but they should help you understanding how powerful hydrators can be, and how you can compose them to solve complex problems.

You may also check the chapters in the documentation about the Aggregate Hydrator and Hydration Strategies, which were designed specifically to solve your problem.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for answer. How should I get product from just an id ? you mean I should get product from database in ProductHydrator ?
This example assumes that you are fetching all fields for products, shops, addresses and users. If you want to go the lazy loading way, it gets waaaaaaaaaay more complex.
Aww , I see . Which method is more efficient ? in your example we should join different tables.Is it better or lazy loading ?
Really depends on the case. This eager approach is the most efficient in most cases, since your UserEntity is likely making use of all 3 child nodes. If you want to look into lazy loading, then you should really either look into Doctrine ORM (I wrote about it at ocramius.github.io/presentations/… ) or build it with something like ProxyManager ( github.com/Ocramius/ProxyManager , but only if you really need to keep Zend\Db)
I faced a problem with joining table in this approach , homonymous field names merge together and causes bug! , What can I do to overcome this problem ?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.