How to extend the skeleton application ZF2 - objects with foreign keys

The ZF2 skeleton app works perfectly according to the Zend user guide. But now I'm running circles trying to expand the application so that the album artist is no longer a string, but the foreign key of the artist table in my db.

I created all the necessary models, controllers, views for creating, editing and viewing artists, which also works great. But how can I combine these two so that the name of the artist is on my list of albums?

Am I using a hydrator strategy as suggested here ? If so, how to implement this? The Zend \ Stdlib \ Hydrator \ Strategy manual does not tell me where to register the hydrator strategy. Yes, there is a short implementation code:

$foo = new Foo(); $foo->setFoo("bar"); $foo->setBar("foo"); $hydrator = new ClassMethods(); $hydrator->addStrategy("foo", new Rot13Strategy()); 

But where does it go? In my AlbumController? And why does everyone say hydrators are "mostly used for molds"?

Or not the giant, what am I looking for in the end? Another thing that I constantly encounter when looking for a solution is dependency injection. Again I found this kind of tutorial , but in using classes A, B and C and not telling me where all these code fragments go, It helps a lot to understand the concept.

I think that what I want to do is quite common, and I staggered that I could not find a single textbook on the real world. After several hours of research, I am sure that I am very close to a breakthrough - but I no longer see it and need a push. Thanks: -)

+4
source share
1 answer

Hydrators are used when you need to get data in or out of an object / object, which can be when using a form, as well as when saving or loading an object from storage.

I would not use Hydrator to populate your objects with related objects (for example, to add an antist object to your album). I would leave it up to your services / cartographers.

Here is an example of how I will do this:

Album.php

 <?php class Album { // .. properties / getters/setters etc .. public function setArtist(ArtistInterface $artist) { $this->artist = $artist; } public function getArtist() { return $this->artist; } } 

AlbumHydrator.php

this may change, you will use getters / setters or properties, look at the base hydrators to decide which route you want to take.

Your hydrator will take the collected objects and return the data that you need either to display the form, or to maintain persistence, etc.

 <?php class AlbumHydrator // extends Zend\Stdlib\Hydrator\ClassMethods { public function extract($object) { return array( 'artist_id' => $object->getArtist()->getId(), 'albumn_name' => $object->getAlbumName() ) } // .. etc } 

AlbumService.php

 <?php use Zend\ServiceManager\ServiceManagerAwareInterface; use Zend\ServiceManager\ServiceManager; class AlbumService implements ServiceManagerAwareInterface { /** * Get an album, we'll also load any related objects here * * @param int */ public function find($id) { $album = $this->_getAlbumMapper()->find($id); $artist = $this->_getArtistMapper()->findByAlbum($id); $album->setArtist($artist); return $album; } /** * Get the Mapper * * @return Application\Mappers\AlbumMapper */ protected function _getAlbumMapper() { return $this->getServiceManager() ->get('AlbumMapper') ; } // .. } 

You must configure your service in the Service Manager configuration as follows:

 'AlbumService' => function($sm) { $mapper = $sm->get('AlbumMapper'); $service = new Application\Service\AlbumService(); $service->setAlbumMapper($mapper); return $service; }, 

Then you use your service to create a graph of the object you need. You will have separate cartographers for each of the entities, and services can use mappers to generate the required objects.

You usually have a Hydrator for each of the entities, and cartographers will use them to populate objects for you. It will depend on your implementation, you can use TableGateway or something instead of cartographers, which will work fine anyway.

An example is now accessing your objects when inside your controller

SomeController.php

 public function albumAction() { $id = (int) $this->params()->fromRoute('id', FALSE); if( ! $id) { // do something with errors etc .. return $this->redirect()->toRoute('default_route', array( 'controller' => 'index', 'action' => 'index' )); } $request = $this->getRequest(); $album = $this->getServiceLocator()->get('AlbumService')->find($id); $artistName = $album->getArtist()->getName(); return new ViewMdoel( 'album' => $ablum, 'artistName' => $artistName ); } 

Custom object graphs when using collections are a bit more complicated, but I would try to use lazy loading and virtual proxies for such an installation, which basically delays the loading of objects you need until you require them, check:

http://phpmaster.com/intro-to-virtual-proxies-1/ http://phpmaster.com/intro-to-virtual-proxies-2/

+7
source

All Articles