This will be the first part of a longer series in using Doctrine 2 in a Zend Framework 2 application. We will be building a very simple blogging application, making use of the most common use-case-scenarios for Doctrine 2. The way i see it right now, most people are interested in the basics of using the ORM in Zend Framework 2 correctly. Examples for use-case-scenarios like @OneToOne, @OneToMany and @ManyToMany are missng and even setting up the Zend\Form and the specific Hydrators correctly still remain a little mystery to some (even to me!).
In this first part we will be building a simple entity for our posts. We will be building a form to add, edit and delete our post entity. We will not cover any relationships in this first example, as this simply is too big for a single blogpost.
The concept
First of all i assume that you guys have successfully integrated Doctrine 2 into your Zend Framework application. If this is not the case please visit my Blogpost and start integrating Doctrine 2 first.
As mentioned before, we will build a simple blogging application. For this we will do the following things:
- Create a new Module named Blog
- Create new routes for our module
- Create a controller for our posts stuff
- Create two forms for the following purposes (add, edit, delete)
- Manage Database interaction via Doctrine 2
Are you ready to start? I am, so let’s continue…
Creating the new Module
To start our new Module create the following folder- and file-structure in your Zend Framework 2 appliction:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | ./module ./Blog ./config | ./module.config.php ./src | ./Blog | ./Controller | ./PostController.php | ./Entity | ./Post.php | ./Form | ./PostForm.php | ./PostFieldset.php ./view | ./blog | ./post | ./add.phtml | ./delete.phtml | ./edit.phtml | ./index.phtml ./Module.php |
As everything will be running within the namespace Blog we need to make this namespace known to the Zend Framework 2 application. For this edit the the following file to given content:
1 2 3 4 5 6 7 8 9 10 11 | ./config/application.config.php <?php return array( 'modules' => array( 'Application', 'Blog', //... depending on your setup more namespaces/modules ), // ... ); |
Next thing to do is to edit the Module.php. Nothing too special here, basic configuration stuff.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?php namespace Blog; class Module { public function getConfig() { return include __DIR__ . '/config/module.config.php'; } public function getAutoloaderConfig() { return array( 'Zend\Loader\StandardAutoloader' => array( 'namespaces' => array( __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__, ), ), ); } } |
Current status
If now we call our application with our wanted route e.g. http://blog.loc/post we will be welcomed with the following message:
The requested URL could not be matched by routing.
We haven’t done the required routing yet, so let’s go ahead and do that now. Edit ./Blog/config/module.config.php. The highlighted lines are the relevant ones (the ones where usually the copy and paste errors happen).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <?php namespace Blog; return array( 'router' => array( 'routes' => array( 'post' => array( 'type' => 'segment', 'options' => array( 'route' => '/post[/:action][/:id]', 'constraints' => array( 'action' => '[a-zA-Z][a-zA-Z0-9_-]*', 'id' => '[0-9]+', ), 'defaults' => array( 'controller' => 'Blog\Controller\Post', 'action' => 'index', ), ), ), ), ), 'controllers' => array( 'invokables' => array( 'Blog\Controller\Post' => 'Blog\Controller\PostController' ), ), 'view_manager' => array( 'template_path_stack' => array( 'blog' => __DIR__ . '/../view', ), ), 'doctrine' => array( // ... doctrine config ) ); |
Status Update
If you call http://blog.loc/post now, you’ll be granted following message:
The requested controller could not be mapped to an existing controller class.
And this is good, it simply tells us that we shouldn’t slack off and start creating our controller class now.
Creating the Controller
Since all that’s missing for the SetUp is a Controller, let’s create this. Open the ./Blog/Controller/PostController.php and modify it with the following content.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?php namespace Blog\Controller; use Zend\Mvc\Controller\AbstractActionController; class PostController extends AbstractActionController { public function indexAction() {} public function addAction() {} public function editAction() {} public function deleteAction() {} } |
Another StatusCheck
As long as you have created all files and followed the instructions in this tutorial, you should now be presented with an empty site calling http://blog.loc/post (or not empty, in case you have modified index.phtml alrady)
Creating the Doctrine 2 Entity
Since we have the basic structure of our Zend Framework 2 Blogging Application in place it is now time to define and create our Doctrine 2 Entity. Since we will only be covering the basics for now, our Entity will look like the following:
- Entity name: Post
- Property ID: Primary identifier
- Property TITLE: Title of our Blog Post
- Property TEXY: Content of our Blog Post
And for the start this is all. We will cover Tags and Author relationships within future Blogposts, but for now this is enough. So let’s start creating our Entity. Open ./Blog/Entity/Post.php and modify it given this content:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | <?php namespace Blog\Entity; use Doctrine\ORM\Mapping as ORM; /** * Entity Class representing a Post of our Zend Framework 2 Blogging Application * * @ORM\Entity * @ORM\Table(name="posts") * @property int $id * @property string $title * @property string $text */ class Post { /** * Primary Identifier * * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") * @var integer * @access protected */ protected $id; /** * Title of our Blog Post * * @ORM\Column(type="string") * @var string * @access protected */ protected $title; /** * Textual content of our Blog Post * * @ORM\Column(type="text") * @var string * @access protected */ protected $text; /** * Sets the Identifier * * @param int $id * @access public * @return Post */ public function setId($id) { $this->id = $id; return $this; } /** * Returns the Identifier * * @access public * @return int */ public function getId() { return $this->id; } /** * Sets the Title * * @param string $title * @access public * @return Post */ public function setTitle($title) { $this->title = $title; return $this; } /** * Returns the Title * * @access public * @return string */ public function getTitle() { return $this->title; } /** * Sets the Text Content * * @param string $text * @access public * @return Post */ public function setText($text) { $this->text = $text; return $this; } /** * Returns the Text Content * * @access public * @return string */ public function getText() { return $this->text; } } |
Take careful not of all the @ORM\Annotations! This is how Doctrine 2 works. The Setter- and Getter-Methods are pretty basic, no need to go into detail for those.
Above line 15 we first define that this class represents a Doctrine 2 Entity. We tell Doctrine 2 that our tableName will be “posts”.
Inside of the class we define the properties. Notable here is the definition of the primary key using the @ORM\Id and @ORM\GeneratedValue Annotations.
The Database
Since Doctrine 2 is an all around Framework, we can potentionally use the command line to create the database table based on this Entity-Class. Personally though i simply don’t have enough knowledge to do so, i create the database manually given following script.
1 2 3 4 5 6 7 | CREATE TABLE `posts` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `title` VARCHAR(50) NOT NULL, `text` LONGTEXT NOT NULL, PRIMARY KEY (`id`) ) |
To get our indexAction() running directly, let’s create one simple entry to this table manually, too.
1 2 3 4 | INSERT INTO `posts` (`title`, `text`) VALUES ( 'Hello ZF2 Blog', 'This is our first sample blogging application using Zend Framework 2 and Doctrine 2' ); |
The Index Overview
Since now we have our Database ready, we can start to work with Doctrine 2s EntityManager. Before working on the indexAction() we need to add something to our Controller. This is what my controller looks like now:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | <?php namespace Blog\Controller; use Zend\Mvc\Controller\AbstractActionController; use Doctrine\ORM\EntityManager; class PostController extends AbstractActionController { /** * @var EntityManager */ protected $entityManager; /** * Sets the EntityManager * * @param EntityManager $em * @access protected * @return PostController */ protected function setEntityManager(EntityManager $em) { $this->entityManager = $em; return $this; } /** * Returns the EntityManager * * Fetches the EntityManager from ServiceLocator if it has not been initiated * and then returns it * * @access protected * @return EntityManager */ protected function getEntityManager() { if (null === $this->entityManager) { $this->setEntityManager($this->getServiceLocator()->get('Doctrine\ORM\EntityManager')); } return $this->entityManager; } public function indexAction() {} public function addAction() {} public function editAction() {} public function deleteAction() {} } |
What happened here? Well, this is pretty simple. We add a property to our Controller called $entityManager. This basically is the glue between our EntityModels and our Database. We have defined the Service Doctrine\ORM\EntityManager while setting up Doctrine 2 for Zend Framework 2 and now make use of it. If you work with Entities in multiple Controller and always use the same EntityManager i suggest extracting these function into a separate Controller-class from which you can extend your Controllers from. Given Example, personally i created a EntityUsingController which extends the AbstracActionController and my PostController extends the EntityUsingController. It’s to keep my code clean and separated and makes each class only worry about the things they need to.
But enough talk, we have set this up now, let’s create our indexAction()!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?php // ... NameSpace and use statements class PostController extends AbstractActionController { // ... EntityManager stuff public function indexAction() { $repository = $this->getEntityManager()->getRepository('Blog\Entity\Post'); $posts = $repository->findAll(); return array( 'posts' => $posts ); } // ... Other Actions } |
This will fetch all current posts from the database and assign it to the view variable ‘posts’. To be able to view all Posts now we need to create our view, for this we edit ./Blog/view/blog/post/index.phtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <?php $title = 'Post Overview'; $this->headTitle($title); ?> <h1><?php echo $this->escapeHtml($title); ?></h1> <p> <a href="<?php echo $this->url('post', array('action'=>'add'));?>">Add new Post</a> </p> <?php foreach ($posts as $post) : ?> <article> <h1><?php echo $this->escapeHtml($post->getTitle());?></h1> <p> <?php echo $this->escapeHtml($post->getText());?> </p> <aside> <ul> <li><a href="<?php echo $this->url('post', array( 'action'=>'edit', 'id'=>$post->getId() )); ?>">Edit this Post</a></li> <li><a href="<?php echo $this->url('post', array( 'action'=>'delete', 'id'=>$post->getId() ));?>">Delete this Post</a></li> </ul> </aside> </article> <?php endforeach; ?> |
There’s not too many things happening here. We set the Title for this page, we give it an ‘add’ links, as well as edit and delete links for each post stored in our database. Feel free to modify the output as desired… Looking at the page now you should see one Blogpost, the add-links to http://blog.loc/post/add as well as the edit- and delete-link to http://blog.loc/post/(edit|delete)/1. In case of the urls not being displayed as desired, check back at the routing setup of this blogpost.
Setting up the Form
Before we go into details of the addAction() we first define our formular. For this we will be using a Form and a Fieldset. Why both? Because for later use with relationships this will become our standard way of doing things, so we may as well use the little ‘advanced’ method for our basic purposes, too.
If you have not yet looked too much into detail of Zend\Form or Zend\Form\Fieldset i strongly suggest you reading about Zend\Form Features of Zend Framework 2 at Michael Gallegos Blog. He explained it very well and ten times better than i possibly could…
Let’s start by creating the Fieldset first. The fieldset will hold the information required for a post. This is the ID (for editing purposes), the title and the text. Since we’re working on a Fieldset we will also include an Interface to be able to define our filtering- and validation-rules in there.
I will give you the code now and then we will go over it step by step, as there’s a lot of things happening here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | <?php namespace Blog\Form; use Blog\Entity\Post; use Stdlib\Model\Registry; use Zend\Form\Fieldset; use Zend\InputFilter\InputFilterProviderInterface; use DoctrineORMModule\Stdlib\Hydrator\DoctrineEntity; class PostFieldset extends Fieldset implements InputFilterProviderInterface { public function __construct() { parent::__construct('post'); $em = Registry::get('entityManager'); $this->setHydrator(new DoctrineEntity($em)) ->setObject(new Post()); $this->setLabel('Post'); $this->add(array( 'name' => 'id', 'attributes' => array( 'type' => 'hidden' ) )); $this->add(array( 'name' => 'title', 'options' => array( 'label' => 'Title for this Post' ), 'attributes' => array( 'type' => 'text' ) )); $this->add(array( 'name' => 'text', 'options' => array( 'label' => 'Text-Content for this post' ), 'attributes' => array( 'type' => 'textarea' ) )); } /** * Define InputFilterSpecifications * * @access public * @return array */ public function getInputFilterSpecification() { return array( 'title' => array( 'required' => true, 'filters' => array( array('name' => 'StringTrim'), array('name' => 'StripTags') ), 'properties' => array( 'required' => true ) ), 'text' => array( 'required' => true, 'filters' => array( array('name' => 'StringTrim'), array('name' => 'StripTags') ), 'properties' => array( 'required' => true ) ) ); } } |
WOW, let’s go over this now. First let’s have a look at the use statements. We include our Entity\Post to be able to bind the form data to our Entity later. Then on line 6 we include Stdlib\Model\Registry. This is a SingletonRegistry-Class i wrote in a separate namespace. You need to do this, too. Not really in a separate namespace, but it makes a lot of sense there. We use this Registry class to ‘transfer’ the EntityManager from our Controller down to the Fieldset. Right now this is the simplest and cleanest solution to do this – certainly not the best, but we will have to wait for the ZF/Doctrine Devs to come up with a better solution to do this.
We need the EntityManager for the DoctrineEntity-Hydrator. This is the Hydrator we include on line 11 and i used to map form data to doctrine entities.
Next to that we use the Fieldset and InputFilterProviderInterface. The later is used to tell the Form on where to find our inputFilters and Validation-rules. This is where the getInputFilterSpecification() function comes into play. Simply take a look at it and i am sure you get a grip on how it works.
The next interesting lines are 22 and 23. This is where we actually set the Hydrator for our form and give it the EntityManager (therefore the Registry) and we set the Forms Object to a new Post(). This tells the form that we’re actually submitting data. The DoctrineHydrator then grabs all Forms Data and hydrates it into the Form Object.
Once again, if my explanation seems a little vague, i strongly suggest Michael Gallegos blog article about it.
PostForm.php
The PostForm is a little simpler to understand than the PostFieldset. We Add some basic elements like a submit-button and a Cross-Site-Request-Forgery-Protection, we add the PostFieldset and we tell the Form what to validate with the setValidationGroup(). The rest should be pretty simple to understand.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | <?php namespace Blog\Form; use Zend\Form\Form; use Zend\InputFilter\InputFilter; use Zend\Stdlib\Hydrator\ClassMethods; class PostForm extends Form { public function __construct($name = null) { parent::__construct('post'); $this->setAttribute('method', 'post') ->setHydrator(new ClassMethods()) ->setInputFilter(new InputFilter()); $this->add(array( 'type' => 'Blog\Form\PostFieldset', 'options' => array( 'use_as_base_fieldset' => true ) )); $this->add(array( 'name' => 'security', 'type' => 'Zend\Form\Element\Csrf' )); $this->add(array( 'name' => 'submit', 'attributes' => array( 'type' => 'submit', 'value' => 'Go', 'id' => 'submitbutton' ) )); $this->setValidationGroup(array( 'security', 'post' => array( 'title', 'text' ) )); } } |
Displaying the Form
Let’s quickly check if we have done everything correct. Modify our controllers addAction() with the following content and remember to include the required classes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <?php namespace Blog\Controller; use Zend\Mvc\Controller\AbstractActionController; use Doctrine\ORM\EntityManager; use Stdlib\Model\Registry; use Blog\Entity\Post; use Blog\Form\PostForm; class PostController extends AbstractActionController { // ... Other Stuff public function addAction() { $em = $this->getEntityManager(); Registry::set('entityManager', $em); $post = new Post(); $form = new PostForm(); $form->bind($post); return array( 'form' => $form ); } // ... edit/deleteAction() } |
Nothing much happening here yet. We get the EntityManager and set it inside the registry, call an empty Post(), the PostForm(), bind the Post to the Form and return the form to our view. So let’s display the form now. Edit ./Blog/view/blog/post/add.phtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <h1>Add a new Post</h1> <?php $form->setAttribute('action', $this->url('post', array('action'=>'add'))) ->prepare(); echo $this->form()->openTag($form); $postFieldset = $form->get('post'); echo $this->formHidden($form->get('security')); echo $this->formHidden($postFieldset->get('id')); echo $this->formRow($postFieldset->get('title')); echo $this->formRow($postFieldset->get('text')); echo $this->formInput($form->get('submit')); echo $this->form()->closeTag($form); |
Nothing too special here, pretty standard stuff. Only thing notable is don’t get confused by $form and $this->form(). $form is my assigned view Variable and is the Zend\Form essentially. $this->form() is a ViewHelper to render Form-Specific stuff. And that’s it.
Call your application and see if the form get’s displayed (it should).
Saving Doctrine 2 Entities
Let’s now take a look at the final addAction() and how to save the Doctrine 2 Entities to our Database. To sum it up what we have to do:
- First we initiate the form and the entity
- Then we check if the form is already posted
- If its posted, the Post data is bound to the form
- Then the form gets validated
- If it’s valid the entity should be saved
- And let’s get redirected to the index on success
A couple of lines to describe things but not even many more lines to do it. Here we go:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public function addAction() { $em = $this->getEntityManager(); Registry::set('entityManager', $em); $post = new Post(); $form = new PostForm(); $form->bind($post); $request = $this->getRequest(); if ($request->isPost()) { $form->setData($request->getPost()); if ($form->isValid()) { $em->persist($post); $em->flush(); $this->redirect()->toRoute('post'); } } return array( 'form' => $form ); } |
Fill out the form, send it and you will have your entity saved to the database. You will notice that the Entities are sorted by their ascending ID. If you want to change this behavior check our the Doctrine 2 Manual on how to do that
Manuals are fun!
Editting Entities
After having our entities added to the database, the next logical step is to edit them because we made a spelling mistake, like there probably are numerous in this post ![]()
For this we do not need to change our form at all. We don’t even need to change our view, other than to copy this inside the edit.phtml and change the title to edit instead of add. The main thing different is the controller part. Here we first need to get the actual entity before editing. Here is the controller and the view:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | public function editAction() { $id = (int) $this->params('id', null); if (null === $id) { return $this->redirect()->toRoute('post'); } $em = $this->getEntityManager(); Registry::set('entityManager', $em); $post = $em->find('Blog\Entity\Post', $id); $form = new PostForm(); $form->bind($post); $request = $this->getRequest(); if ($request->isPost()) { $form->setData($request->getPost()); if ($form->isValid()) { $em->persist($post); $em->flush(); $this->redirect()->toRoute('post'); } } return array( 'form' => $form, 'id' => $id ); } |
Test this by using the edit links of your index view and you will be able to edit your entities.
Removing Entities
Removing of Entities is pretty simple. I will simply give you the EntityManager-Snipplet required, but of course you should build a form around it, asking for a removal confirmation, etc… ![]()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public function deleteAction() { $id = (int) $this->params('id', null); if (null === $id) { return $this->redirect()->toRoute('post'); } $em = $this->getEntityManager(); $post = $em->find('Blog\Entity\Post', $id); $em->remove($post); $em->flush(); $this->redirect()->toRoute('post'); } |
Hardcore removal, only for experts! ![]()
Final Conclusion
Using bare data-models / Entities and save them to the database using Doctrine 2 is a pretty simple task. The additional hassle we did here with the Registry Class will come in handy later.
I hope that i will be able to give you tutorials using relationships as soon as possible. Current standing of the DoctrineORMModule however doesn’t allow me to edit my Entities using relationships without errors. I’m sure it won’t last too long for until those get fixed. If it lasts a little too long, i will at least display the possibilities to ADD Entities to the database that contain relationships, as this part works.
Until then i wish you all a great time using Zend Framework 2 and Doctrine 2 together.

57 Responses to A Blog Application Part 1 – Working with Doctrine 2 in Zend Framework 2
Angusfr May 1, 2013
Hi,
i would like to know how can you use the findAll() function on a repository because i can’t do it at all :’(
i can find one object using this :
$album = $this->getEntityManager()->find(‘Album\Entity\Album’,’1′);
but when i use this, 100% fail :
$album = $this->getEntityManager()->getRepository(‘Album\Entity\Album’)->findAll();
Zf2 can’t find the findAll() function but he find the find() function my entity manager.
Someone can explain me this please ?
Some Mistake April 30, 2013
can you help me Sam? I can’t find any solution in the internet about this…
i have login fieldset:
$this->add(array(
‘type’ => ‘Zend\Form\Element\Email’,
‘name’ => ‘email’
));
$this->add(array(
‘type’ => ‘Zend\Form\Element\Password’,
‘name’ => ‘password’,
));
Then, I added it into the login form:
$loginFieldset = new LoginFieldset($serviceManager);
$loginFieldset->setUseAsBaseFieldset(true);
$this->add($loginFieldset);
In controller I bind form and entity:
$form = new LoginForm($this->serviceLocator);
$user = new Entity\User();
$form->bind($user);
but in my view, i can’t echo rows of the form:
$this->formRow($form->get(‘email’)); <- it shows: Catchable fatal error: Object of class Zend\Form\View\Helper\FormRow could not be converted to string in …
Can you give any suggestions?
Sam April 30, 2013
I may be wrong, but isn’t it that even on the basefieldset you still need to access it first? Like
$form->get(‘fieldsetname’)->get(‘email’);
Check the HTML-Sources to see what fieldnames they actually have
Some Mistake April 30, 2013
U a genius!) So fast and so right!) Thanks!
nomen April 27, 2013
Hey Sam!
I’m very appreciate you for writing this article!
But maybe you could show your Registry class (on github gist for example) and describe where exactly did you placed it?
It’s will be very helpfull for me and others.
Sam April 27, 2013
This part is actually very outdated :S You are to use the ServiceManager to do this kind of stuff. Please refer to this Blogpost to see about the details.
nomen April 27, 2013
Hi everyone.
I’ve stopped at “the index overview” because of error. It says that:
“The class ‘Blog\Entity\Post’ was not found in the chain configured namespaces …”
And it was because of at the
./Blog/config/module.config.php file in article example were no the doctrine config (at 34th line). I’ve added such code:
and everything start working correctly.
Sam April 27, 2013
Yep, you definitely need that. This however has been pointed out inside the article, where i linked my other blog post about how to set up Doctrine for your projects
Thanks for clarifying it for the others though! 
nomen April 27, 2013
Ah, you right!!
)
Btw, your links at “the concept” part is pointing now to the current article, not to “installing doctrine 2 …”
Simon April 18, 2013
Dit you try the hydrator on an object with an many-to-one relation? Works fine for me until the relation value should be null. Do you have any clue on this?
http://stackoverflow.com/questions/16061402/zf2-doctrine2-doctrineobject-hydrator-null-value-for-manytoone-relation
Billy Scholtz March 13, 2013
Thank you for your blog. Without it, I would have struggled a lot to get going in ZF 2. Bought all the books(3 of them) none as current on ZF2 as your blog.
Please keep up the good work.
Jack January 22, 2013
One problem more I have. Registry::set(‘entityManager’, $em); not working in my controller in add action..(I have use Stdlib\Model\Registry namespace in PostController) I’m getting HTTP 500 error and this is a reason:
PHP fatal error: Class “Stdlib\\Model\\Registry” not found.
Sam January 22, 2013
The Registry-Stuff is outdated. I will follow up on that topic in approximately 2 weeks, until then please refer to https://github.com/doctrine/DoctrineModule/blob/master/docs/hydrator.md#a-complete-example-using-zendform
Apart from that, it’s ‘Yourmodulename\Stdlib\Model\Registry’
Jack January 22, 2013
Thanks again for your help. Changing this lines in fieldset class resolved issue:
use Zend\Stdlib\Hydrator\ClassMethods as ClassMethodsHydrator;
$this->setHydrator(new ClassMethodsHydrator(false))
->setObject(new Post());
help me and form starts working. For what we need this hydrator from DoctrineEntity & EntityManger here if it working fine with ClassMethodsHydrator? Setting hydrator as DoctrineEntity gives us anythink better? I’m newbie sry if my questions are so lame
Jack January 22, 2013
this tutorial not working for me:
404 Not Found
The requested URL /zf2test/ZendSkeletonApplication/public/blog/ was not found on this server.
Can you send full code of ./Blog/config/module.config.php?
Sam January 22, 2013
Hey, the requested URL appears to be fully qualified. This implies that you did not set-up the VirtualHost for your project.
If you carefully follow all the instructions in the Blog-Article, you will have a working Solution. I suggest you start checking for errors at the very beginning of installing the ZF2-Application.
The config you’ve requested is pretty much visible apart the doctrine-configuration. That post is linked, too.
Jack January 22, 2013
Thanks for your answer Sam. Hmm.. but it means that ZF2 apps will not work on relative paths? Application module works fine so new created module should too I think.. In my opinion host shouldn’t be “condition” to work, it should be only an option. I wanna to make flexibly app which I can just put in folder and work from relative URL on the server or link to domain or host if I rly need it.
Sam January 22, 2013
I’m sure it works relatively, too, but i have no clue about those error messages in there. Biggest suggestion would be: is your module registered in application.config.php? From there check the route, the controller, the action, the view file.
Jack January 22, 2013
Yes module is set in config file, other files are correct too controlers etc. But in my project now working only this http://serwer/zf2test/ZendSkeletonApplication/public. Nothing more for example i cannot use http://serwer/zf2test/ZendSkeletonApplication/public/application or http://serwer/zf2test/ZendSkeletonApplication/public/application/index etc. I’m getting 404 error. I have clean Zend skeleton project and integreted doctrine only from your blog post.
Sam January 22, 2013
Sounds like .htaccess file isn’t working. :S Can’t help out too much with that though
Jack January 22, 2013
I have server on VirtualBox with debian. I’m working on win7. I setup host and now http://zf.dev/post/ is working fine for me, htaccess working too so i don’t understand why it wasn’t work by relative path
. Btw how now and where I can set blog route? I wanna to call just module blog and http://zf.dev/blog/ should display http://zf.dev/post/index action.
Sam January 22, 2013
Routes are inside module.config.php Check the manual for differences between literal and segment routes, as well as what exactly a child-route is.
Sam January 22, 2013
The Registry-Stuff is outdated. I will follow up on that topic in approximately 2 weeks, until then please refer to https://github.com/doctrine/DoctrineModule/blob/master/docs/hydrator.md#a-complete-example-using-zendform
Mateusz December 24, 2012
Sam, thank you for great tutorial and devoting you time for writing a post. We wait for the next
Mosak December 13, 2012
Hi Sam,
You said about “Stdlib\Model\Registry”:
“Hi there, it’s not a Zend-Class. By the time of writing that code, there was simply no other elegant solution to get the Doctrine EntityManager down to several Fieldsets. Looking over at Github now there appears to be a way which i will cover sometime in the future, too.”
Please tell what is the other way:) Thanks in advance.
Michael December 11, 2012
Hi Sam, thanks for explaining how to install doctrine in zf2 and how to use it. Everthing works fine, except the Stdlib\Model\Registry.
The class Stdlib\Model\Registry is not available in my zend\stdlib repository. Is there another solution or can you post the class?
Adil December 1, 2012
Hi Sam, thanks for taking time to publish these very helpful articles which will help many newbies like me.
I have some very silly basic questions about complicated arrays.
I am unable to fully understand so many multi-dimensional arrays in module.config.php. Is there any graphical representation or a detailed explanation or documentation about what these all arrays are about ?
How one can manage to avoid making mistakes in these arrays while making any new addition ?
May be you can refer to any existing helpful article which explain in detail about the structure of these arrays. I hope you will help me.
Sam December 1, 2012
This pretty much boils down to experience, a good IDE, and at first a good coding style. Always intend a level of a multi dimensional array. Basically each new dimension will be introdudes as ‘key’ => array(/** new dimension */). A list of all possible keys i don’t have myself, but i’ll try to make a little more basic blog about this possibly sometime in the future.
Adil December 1, 2012
Thanks Sam for your response. One more question from your above mentioned code about /Blog/config/module.config.php:
Why you inserted ‘post’ => array(
BETWEEN
‘routes’ => array(
AND
‘type’ => ‘segment’,
Can we insert it at any point for example AFTER
‘options’ => array(
If not then why not ?
I hope you will again answer my question.
Sam December 1, 2012
Basically you have to read this part like this: Configuration -> Router configuration -> Route-Name -> Type-Configuration -> Additional Type Options, etc…
Maybe you’d be well suggested reading something more about arrays in general? If you have trouble understanding this, then underlying features of ZF2 will be quite a few miles away for you
dunpeal69 November 16, 2012
Just a note about database schema generation with Doctrine 2 CLI (don’t know if someone is interested by this information but I didn’t saw that in this interesting article) :
I’m using latest version of ZF2 and Doctrine2 plugin by cloning them from their respective git repositories and I tried today :
Then it has automatically created the associated tables for my model
I hope this can help someone.
Sam November 16, 2012
Thanks for the hint. This is certainly something very useful and i will check this out and probably dedicate a post for this. Model first is a development approach i highly appreciate!
Tommy2002 November 6, 2012
Hello,
I would be interested how to use Zend 2 and Doctrine 2 can access two databases. Can someone help me?
Thank you
Thomas
Sam November 6, 2012
Take alook at the doctrine configuration in my previous post. Basically if another module needs another connection, you’d simply change the connection driver for that module. I haven’t done this, but shouldn’t be too difficult, i may suggest you trying to ask in either #zftalk or #doctrine at freenode.ned IRC
Bba November 3, 2012
Hi Sam,
Thanks for the tutorial, It helped a lot
However you have a typo error in your delete post
$em->remove($album);
Am guessing it should be
$em->remove($post);
Good one bro, keep up the good work
God Bless!!!
Sam November 4, 2012
Thanks for the hint, fixing it asap. You may also be interested that very soon (i.e. roughly a week from now) i’ll be redoing this series with little more clean code
Bba November 4, 2012
will be looking forward to it
cheers
Mukoro Godwin October 27, 2012
Every thing on the zend framework site is confusing but with your tutorial my zf2 is running. Thanks so much for sharing I would keep following
Máté Kocsis October 23, 2012
Hi Sam!
Your tutorial helped me a lot, but now I am facing to a serious problem.
When I call $form->getData() after the form is submitted, it shows that only the two date fields have value, neither the id, nor other collections and associations (e.g. the ‘author’ select field which is a foreign key in my table)… Could you give me some hint? It seems so weird that some fields have value, and the most of them don’t.
I followed your and Michael Gallego’s instructions to create the form.
Sam October 23, 2012
Hey there, im glad it helped. Please make sure that all your fields are getting validated. Only validated data will be returned from any form.
Máté Kocsis October 23, 2012
Ahh! Such a great idea!
Thanks a lot! Keep up posting!
bl4de October 18, 2012
Hi Sam,
Great work, by the way I created a little bash script for creating ZF2 module’s folders structure. Here’s link:
https://dl.dropbox.com/u/67895339/zf2crmod.sh
Greetings,
bl4de
Wesley Overdijk October 16, 2012
“Right now this is the simplest and cleanest solution to do this – certainly not the best, but we will have to wait for the ZF/Doctrine Devs to come up with a better solution to do this.”
May I suggest using a controller factory? In stead of using an invokable, use a factory method, and inject the form into the controller. Here, you’ll have the ServiceManager. And as long as you’re using the Doctrine module, you’ll find the EntityManager in here, too. Just inject the dependencies and it’s as clean as it’s going to get. Simply implement a getForm, and setForm in your controller and handle the rest in your factory method. (basically building the Doctrine hydrator using the entity manager).
Just a suggestion. Registries are not cool anymore, but nice thinking
Good article.
Sam October 16, 2012
Thank you for your comment. The Problem is getting the ServiceManager down to the fieldset level. Last time i’ve checked i’ve seen an approach like you’ve just suggested. However at the time of writing this tutorial – as sadly as it sounds – but registry WAS the easiest and most productive solution – as noted though, not the best one

And that statement came from one of the main contributors of the Zend\Form Component
Wesley Overdijk October 23, 2012
alrighty, new idea. Populate the form with fieldsets that have pre-defined hydrators in a factory…? Just trying to not have to use the registry haha.
Madhukar October 10, 2012
Hi sam,
Its great tutorial am really going with this. if possible can u make link for downloading source code.
Sam October 10, 2012
Good suggestion, i will soon follow up with Doctrine 2 and Relationships within the next 2 weeks and then will consider putting it all onto github!
Charlie October 7, 2012
How you doing Sam!
So I’ve been going over your tutorial, and I see that you are using zend\stdlib. what exactly is in your class Stdlib\Model\Registry and what’s it for?
Sam October 8, 2012
Hi there, it’s not a Zend-Class. By the time of writing that code, there was simply no other elegant solution to get the Doctrine EntityManager down to several Fieldsets. Looking over at Github now there appears to be a way which i will cover sometime in the future, too.
The Class itself is a simple Registry-Pattern that stores stuff at one place that i’ll be grabbing at another (i.e.: down some fieldset levels)
Sam October 3, 2012
Hello Sam!
Great tutorial. I’m also just starting to use ZF2. I’d like to ask you: does loading a page or making an http request on you local server with ZF2 gets interrupted sometimes because it’s taking too long to load? I had tried ZF1 before I started to use ZF2 and everything was working fine then. Now, sometimes I need to hit refresh to do the same http request. Any non ZF2 page request seems to work fine. I’m using Wamp 2.2 on windows 7. If you could help me out here, I’d truly appreciate it.
Sam October 3, 2012
I don’t know about WAMPP especially. Personally i haven’t had any issues at all that would have been ZF specific. Usually it’s a messed up configuration. But i’m no expert either. All my knowledge is in this blog, and i don’t have more than i wrote down
Charlie October 3, 2012
yeah, you got a fantastic site here!!! I was thinking of doing something similar since there wasn’t anything for true beginners like ourselves out there.
I agree, the configuration isn’t really self explanatory. so all the loading and http requests go through with no problems, the same way as if you were requesting a simple html file?
keep up the great work. I suppose we could probably help each other along the way.
Sam October 4, 2012
Thanks for your input!
wd September 7, 2012
Hi Sam, thanks for the good documented tutorial, can you update your tutorial to validate duplicate records in the database using ZF2 and Doctrine2
Sam September 10, 2012
Hey there, thanks for your reply. This certainly is a valid topic you’re asking about and i will probably do a blog post about that soon
samsonasik August 2, 2012
great tutorial
cy July 31, 2012
krass