Sunteți pe pagina 1din 21

Use Doctrine with the Zend Framework

Integrate the Doctrine ORM tool with a Zend Framework application to simplify data access and manipulation
Vikram Vaswani Founder Melonfire 25 June 2013 (First published 28 May 2013)

Doctrine is an object-relational mapping (ORM) tool for PHP application development. With a modicum of configuration, you can combine it with the Zend Framework so that you can use Doctrine entities to simplify interaction with application data. This article shows you the process for integrating Doctrine 2.3 with a Zend Framework 1.x or 2.x application. The Zend Framework is one of the most popular frameworks for PHP application development. It's easy to get started with, comes with an extensive library of components, and is well-supported by documentation, code samples, and an active community. Zend Framework is also a complete implementation of the Model-View-Controller (MVC) pattern, allowing for more reusable code and a better separation of concerns. Another Zend Framework benefit is that you can easily integrate third-party libraries into a Zend Framework application. Many developers like to pair the Zend Framework with a third-party ORM tool to make it easier to query and manipulate database content by using objects. And one of the most commonly used ORMs is Doctrine, a well-known open source PHP library for database abstraction and manipulation. In this article, I: Explain how to integrate the Doctrine ORM with a Zend Framework application Cover the basics of creating Doctrine entities Explain how to configure the Zend Framework to load Doctrine classes Illustrate the process of using Doctrine entities within Zend Framework action controllers

Before you start


Before you dive into the code, a few notes and assumptions are in order. Throughout this article, I assume that you:
Copyright IBM Corporation 2013 Use Doctrine with the Zend Framework Trademarks Page 1 of 21

developerWorks

ibm.com/developerWorks/

Are conversant with the basic principles of application development with the Zend Framework Understand the interaction between actions and controllers Are familiar with the namespace implementation in PHP 5.3 Have a working Apache/PHP/MySQL development environment Have installed the Zend Framework to your PHP include_path Are familiar with the basics of SQL Have configured your Apache HTTP Server to support virtual hosting and URL rewriting through .htaccess files

If you are unfamiliar with these topics, see Resources for more information. The techniques that are outlined in this article are based on information and ideas from online documentation and from various blog posts by clever PHP developers (see Resources for credits). The techniques were tested with the software versions mentioned later in this section, but they might not work in future versions because of ongoing development and changes. Currently two versions of the Zend Framework are available. The method to integrate Doctrine differs significantly depending on which Zend version that you use. The article reviews the process of integrating Doctrine with each version separately. The versions that are used in this article are: Zend Framework 1.11.11 Zend Framework 2.0.3 Doctrine 2.3.0 The application database is common to both scenarios, so set up the database right at the start.

Setting up the application database


Begin in MySQL by creating tables to hold articles and related publishers, as shown in Listing 1:

Listing 1. Create MySQL tables


CREATE TABLE IF NOT EXISTS article ( id int(11) NOT NULL AUTO_INCREMENT, title text NOT NULL, url text NOT NULL, 'date' date NOT NULL, publisher int(11) NOT NULL, PRIMARY KEY (id) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS publisher ( id int(11) NOT NULL AUTO_INCREMENT, 'name' varchar(255) NOT NULL, PRIMARY KEY (id) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Populate these tables with some sample records, as shown in Listing 2:

Listing 2. Populating the tables


INSERT INTO publisher (id, name) VALUES(1, 'Zend Developer Zone'); INSERT INTO publisher (id, name) VALUES(2, 'IBM DeveloperWorks');

Use Doctrine with the Zend Framework

Page 2 of 21

ibm.com/developerWorks/

developerWorks

INSERT INTO publisher (id, name) VALUES(3, 'Developer.com'); INSERT INTO publisher (id, name) VALUES(4, 'PHP Architect Magazine'); INSERT INTO article (id, title, url, date, publisher) VALUES(1, 'Search and integrate Google+ activity streams with PHP applications', 'http://www.ibm.com/developerworks/xml/library/x-googleplusphp/index.html', '2012-07-10', 2); INSERT INTO article (id, title, url, date, publisher) VALUES(2, 'Getting Started with Zend Server CE', 'http://devzone.zend.com/1389/getting-started-with-zend-server-ce/', '2009-03-02', 1); INSERT INTO article (id, title, url, date, publisher) VALUES(3, 'Integrating Advanced Spring Framework Features with Magnolia CMS', 'http://www.developer.com/java/web/integrating-advanced-spring-frameworkfeatures-with-magnolia-cms.html', '2010-12-13', 3);

Later on, you'll create Doctrine objects that represent these database tables and then use them within Zend Framework controllers to manipulate records in the database.

Initializing a Zend Framework 1.x application


First I explain the process of integrating Doctrine with a Zend Framework 1.x application. To begin, set up a standard Zend Framework 1.x application that provides the context for the code that is shown in this article. Run the Zend Framework tool script (zf.bat on Windows or zf.sh on *NIX) from the command prompt to initialize a new project:
zf.bat create project example

You can now define a new virtual host for this application (such as http://example.localhost/) in your Apache configuration and point the virtual host's document root to the application's public/ directory. If you then browse to this host, you should see the default Zend Framework 1.x welcome page, which is shown in Figure 1:

Use Doctrine with the Zend Framework

Page 3 of 21

developerWorks

ibm.com/developerWorks/

Figure 1. Default start page for a Zend Framework 1.x application

By default, the application namespace is automatically set to Application, and application-specific classes (such as the Doctrine entities that you'll create soon) are stored in $PROJECT/library/ Application/. Create this directory manually. The next step is to add the Doctrine ORM libraries. Download and manually install the libraries from the project website (for more information, see Resources). Copy the contents of the Doctrine/ directory in the project archive to the $PROJECT/library/Doctrine/ directory. Now your Doctrine and Zend Framework libraries are in the same place. The next step is to bind them together. The glue for that is provided by Guilherme Blanco, whose Bisna project provides a ready-made integration for Zend Framework 1.x with Doctrine 2.x. Download the Bisna project archive (for more information, see Resources). Copy the contents of the library/ directory in the project archive to your $PROJECT/library/ directory, and copy the contents of the bin/ directory to your $PROJECT/bin/ directory. At the end of this process, your $PROJECT/library/ folder should look similar to the one shown in Figure 2:

Use Doctrine with the Zend Framework

Page 4 of 21

ibm.com/developerWorks/

developerWorks

Figure 2. The application's library folder

Configuring a Zend Framework 1.x application for Doctrine


The next step is to configure the application to work with Bisna. Open your $PROJECT/configs/ application.ini file and first add a few namespaces to the auto-loader, as shown in Listing 3:

Listing 3. Adding namespaces to the auto-loader


autoloaderNamespaces[] autoloaderNamespaces[] autoloaderNamespaces[] autoloaderNamespaces[] = = = = Bisna Doctrine Symfony Application

Then, add configuration directives to the file, as shown in Listing 4:

Listing 4. Adding configuration directives


; Bisna pluginPaths.Bisna\Application\Resource\ = "Bisna/Application/Resource" ; Doctrine resources.doctrine.classLoader.loaderClass = "Doctrine\Common\ClassLoader" resources.doctrine.classLoader.loaderFile = APPLICATION_PATH "/../library/Doctrine/Common/ClassLoader.php" resources.doctrine.classLoader.loaders.doctrine_common.namespace = "Doctrine\Common" resources.doctrine.classLoader.loaders.doctrine_dbal.namespace = "Doctrine\DBAL" resources.doctrine.classLoader.loaders.doctrine_orm.namespace = "Doctrine\ORM" resources.doctrine.classLoader.loaders.symfony_console.namespace = "Symfony\Component\Console" ; Doctrine Cache resources.doctrine.cache.defaultCacheInstance = default ; "default" cache resources.doctrine.cache.instances.default.id = default resources.doctrine.cache.instances.default.adapterClass = "Doctrine\Common\Cache\ArrayCache" resources.doctrine.cache.instances.default.namespace = "Application_" resources.doctrine.cache.instances.default.options.servers.0.host = localhost resources.doctrine.cache.instances.default.options.servers.0.port = 11211 ; Doctrine DBAL

Use Doctrine with the Zend Framework

Page 5 of 21

developerWorks
resources.doctrine.dbal.defaultConnection = default ; "default" connection resources.doctrine.dbal.connections.default.id = default resources.doctrine.dbal.connections.default.eventManagerClass = "Doctrine\Common\EventManager" resources.doctrine.dbal.connections.default.parameters.driver = "pdo_mysql" resources.doctrine.dbal.connections.default.parameters.dbname = "appdata" resources.doctrine.dbal.connections.default.parameters.host = "localhost" resources.doctrine.dbal.connections.default.parameters.port = 3306 resources.doctrine.dbal.connections.default.parameters.user = "root" resources.doctrine.dbal.connections.default.parameters.password = "guessme"

ibm.com/developerWorks/

; Doctrine ORM resources.doctrine.orm.defaultEntityManager = default ; "default" manager resources.doctrine.orm.entityManagers.default.id = default resources.doctrine.orm.entityManagers.default.entityManagerClass = "Doctrine\ORM\EntityManager" resources.doctrine.orm.entityManagers.default.configurationClass = "Doctrine\ORM\Configuration" resources.doctrine.orm.entityManagers.default.defaultRepositoryClass = "Doctrine\ORM\EntityRepository" resources.doctrine.orm.entityManagers.default.entityNamespaces.app = "Application\Entity" resources.doctrine.orm.entityManagers.default.connection = default resources.doctrine.orm.entityManagers.default.proxy.autoGenerateClasses = true resources.doctrine.orm.entityManagers.default.proxy.namespace = "Application\Entity\Proxy" resources.doctrine.orm.entityManagers.default.proxy.dir = APPLICATION_PATH "/../library/Application/Entity/Proxy" resources.doctrine.orm.entityManagers.default.metadataDrivers. annotationRegistry.annotationFiles[] = APPLICATION_PATH "/../library/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php" resources.doctrine.orm.entityManagers.default.metadataDrivers.drivers.0.adapterClass = "Doctrine\ORM\Mapping\Driver\AnnotationDriver" resources.doctrine.orm.entityManagers.default.metadataDrivers.drivers.0. mappingNamespace = "Application\Entity" resources.doctrine.orm.entityManagers.default.metadataDrivers.drivers.0. mappingDirs[] = APPLICATION_PATH "/../library/Application/Entity" resources.doctrine.orm.entityManagers.default.metadataDrivers.drivers.0. annotationReaderClass = "Doctrine\Common\Annotations\AnnotationReader" resources.doctrine.orm.entityManagers.default.metadataDrivers.drivers.0. annotationReaderCache = default

Update the database credentials that are listed for the default connection to reflect those of your database server host. To enable the use of a command-line script to generate Doctrine entities, you also must update the application bootstrapper, which is located at $PROJECT/application/Bootstrap.php. Listing 5 shows the code for the Symfony namespace:

Listing 5. Updating the application bootstrapper


<?php class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { public function _initAutoloaderNamespaces() { require_once APPLICATION_PATH . '/../library/Doctrine/Common/ClassLoader.php'; $autoloader = \Zend_Loader_Autoloader::getInstance(); $symfonyAutoloader = new \Doctrine\Common\ClassLoader('Symfony', 'Doctrine'); $autoloader->pushAutoloader(array($symfonyAutoloader, 'loadClass'), 'Symfony'); } }

Use Doctrine with the Zend Framework

Page 6 of 21

ibm.com/developerWorks/

developerWorks

Generating Doctrine entities


You're now ready to generate Doctrine entities that you can use within your action controllers. In many cases, you want to generate the entities manually (for more information, see Resources) and then have Doctrine use these entities to create the database. Because you already have an existing database, you can save time by having Doctrine autogenerate stub entities for you to flesh out later. The autogeneration process is a quick way to begin, but it isn't foolproof. For example, you must manually update the generated entities with information about table relationships. To generate the entities from the database, open your command console. Change to the $PROJECT/bin/ directory and run the commands that are shown in Listing 6. (If necessary, change the path to your PHP interpreter.)

Listing 6. Generating Doctrine entities from the database


php doctrine.php orm:convert-mapping --namespace=Application\Entity\ --from-database annotation ..\library\ php doctrine.php orm:generate-entities --generate-annotations="true" --generate-methods="true" ..\library\

The first command in Listing 6 produces annotated Article and Publisher entities that are based on the existing database schema. The second updates these entities to add setter and getter methods. The generated entities are stored in the $PROJECT/library/Application/Entity/ directory, as shown in Figure 3:

Figure 3. Autogenerated database entities

Updating relationship information


As I noted previously, these entities are incomplete and must be updated with relationship information. In the example scenario, many Articles might be published by a single Publisher,
Use Doctrine with the Zend Framework Page 7 of 21

developerWorks

ibm.com/developerWorks/

and so Article has a many-to-one relationship with Publisher. Add this information manually to the $PROJECT/library/Application/Entity/Article.php class by updating it with the annotation shown in Listing 7:

Listing 7. Updating the entities' relationship information


<?php namespace Application\Entity; use Doctrine\ORM\Mapping as ORM; /** * Application\Entity\Article * * @ORM\Table(name="article") * @ORM\Entity */ class Article { /* other annotations */ /** * @var integer $publisher * * @ORM\ManyToOne(targetEntity="Publisher", fetch="EAGER") * @ORM\JoinColumn(name="publisher", referencedColumnName="id") */ private $publisher; /* other annotations and methods */ }

You now are ready to use these entities in your application code.

Using Doctrine in Zend Framework 1.x controllers


With Doctrine configured and all required entities present, you can easily begin to use these entities within action controllers. I'll begin with an easy example: listing articles with their publishers. Save the code in Listing 8 to $PROJECT/application/controllers/ArticleController.php:

Listing 8. Index action


<?php class ArticleController extends Zend_Controller_Action { public function init() { /* Initialize action controller here */ } public function getDoctrineContainer() { return $this->getInvokeArg('bootstrap')->getResource('doctrine'); } public function indexAction() { $doctrine = $this->getDoctrineContainer(); $em = $doctrine->getEntityManager(); $articles = $em->getRepository('\Application\Entity\Article') ->findAll();

Use Doctrine with the Zend Framework

Page 8 of 21

ibm.com/developerWorks/

developerWorks

$this->view->articles = $articles; } }

The ArticleController::indexAction begins by calling the getDoctrineContainer() method to retrieve the DoctrineContainer object. This object's getEntityManager() method retrieves the entity manager, which then retrieves the Article entity through the repository and calls its findAll() method to retrieve all available article records. The resulting collection is then transferred to the view, which iterates over the collection and returns the individual fields of the record by using the entity's getters. Save the view script in Listing 9 to $PROJECT/application/ views/scripts/article/index.phtml:

Listing 9. Index action view script


<h2>Articles</h2> <ol> <?php foreach($this->articles as $article): ?> <li> <a href="<?php echo $article->getUrl(); ?>"> <?php echo $article->getTitle(); ?></a> <br/> <?php echo $article->getDate()->format('d M Y'); ?> | <?php echo $article->getPublisher()->getName(); ?><br/> </li> <?php endforeach; ?> </ol>

Figure 4 shows an example of the output that you see when you browse to the controller URL, http://example.localhost/article/index. (The output is a numbered list of three articles and shows the title, publish date, and website of each article.)

Use Doctrine with the Zend Framework

Page 9 of 21

developerWorks

ibm.com/developerWorks/

Figure 4. Listing records with Doctrine

In a similar vein, you can add a record to the database by using the input that is supplied through a form like the one shown in Figure 5:

Use Doctrine with the Zend Framework

Page 10 of 21

ibm.com/developerWorks/

developerWorks

Figure 5. Web form for creating a new record

Listing 10 provides an example implementation for using such a form:

Listing 10. Create action


<?php class ArticleController extends Zend_Controller_Action { public function init() { /* Initialize action controller here */ } public function getDoctrineContainer() { return $this->getInvokeArg('bootstrap')->getResource('doctrine'); } public function createAction() { $form = new \Application_Form_ArticleCreate; $this->view->form = $form; if ($this->getRequest()->isPost()) { if ($form->isValid($this->getRequest()->getPost())) { $doctrine = $this->getDoctrineContainer(); $em = $doctrine->getEntityManager(); $article = new \Application\Entity\Article; $article->setTitle($form->getValue('title')); $article->setUrl($form->getValue('url')); $publisher = $em->getRepository('\Application\Entity\Publisher') ->find($form->getValue('publisher_id')); $article->setPublisher($publisher);

Use Doctrine with the Zend Framework

Page 11 of 21

developerWorks
$date = new \DateTime($form->getValue('date')); $article->setDate($date); $em->persist($article); $em->flush(); $this->_helper->getHelper('FlashMessenger') ->addMessage('Your submission has been accepted as item #' . $article->getId() . '.'); } } } }

ibm.com/developerWorks/

The code in Listing 10 reads and validates the input that is provided through the web form. Then, the code initializes a new Article entity and uses its setter methods to set its various properties from the form input. The resulting object is then written to the database using the entity manager's persist() and flush() methods. The entity manager also retrieves a Publisher entity from the database (by using the publisher identifier that is provided in the form) and links it to the Article entity through the setPublisher() method. As these listings illustrate, with a little help from the Bisna integration, it's not difficult to use Doctrine 2.3 entities inside a Zend Framework 1.x application. But what if you like to be on the leading edge, and want to integrate Doctrine with a Zend Framework 2.x application? Keep reading.

Initializing a Zend Framework 2.x application


To begin, set up a standard Zend Framework 2.x application that provides the context for the code that is shown in this article. At the time of writing, Zend Framework 2.x doesn't include a tool script. To initialize a new project, download and extract the contents of the Zend Framework skeleton application (for more information, see Resources) to a directory on your system. Define a new virtual host for this application (such as http://example.localhost/) in your Apache configuration. Point the virtual host's document root to the skeleton application's public/ directory. When you browse to this host, you should see the default Zend Framework 2.x welcome page, which is shown in Figure 6:

Use Doctrine with the Zend Framework

Page 12 of 21

ibm.com/developerWorks/

developerWorks

Figure 6. Default start page for a Zend Framework 2.x application

The recommended way to include dependencies (such as Doctrine) in a Zend Framework 2.x application is with Composer. Edit the $PROJECT/composer.json file and add the Doctrine ORM module for Zend Framework 2.x to the project through the entry that is shown in Listing 11:

Listing 11. Adding the Doctrine ORM module to the project


{ "minimum-stability": "alpha", "require": { "php": ">=5.3.3", "zendframework/zendframework": "2.*", "doctrine/doctrine-orm-module": "0.*" } }

Next, run Composer by executing these commands:


php composer.phar self-update php composer.phar install

Composer now starts to download the Zend Framework and Doctrine ORM module libraries and to set up its auto-loader correctly. When that process is complete, your $PROJECT/vendor/ directory should look similar to the one in Figure 7:

Use Doctrine with the Zend Framework

Page 13 of 21

developerWorks

ibm.com/developerWorks/

Figure 7. The application vendor folder

Configuring a Zend Framework 2.x application for Doctrine


The next step is to configure the application to work with Doctrine. Open your $PROJECT/config/ application.config.php file and add Doctrine to the module list, as shown in Listing 12:

Listing 12. Adding Doctrine to the module list


<?php return array( 'modules' => array( 'Application', 'DoctrineModule', 'DoctrineORMModule' ), // other options ), );

By default, the skeleton application includes an Application module and namespace. To add the Doctrine driver to this module's configuration file, edit the $PROJECT/module/Application/config/ module.config.php file and add a doctrine key to the configuration array, as shown in Listing 13:

Use Doctrine with the Zend Framework

Page 14 of 21

ibm.com/developerWorks/

developerWorks

Listing 13. Adding the Doctrine driver


<?php return array( // other options 'doctrine' => array( 'driver' => array( 'Application_driver' => array( 'class' => 'Doctrine\ORM\Mapping\Driver\AnnotationDriver', 'cache' => 'array', 'paths' => array(__DIR__ . '/../src/Application/Entity') ), 'orm_default' => array( 'drivers' => array( 'Application\Entity' => 'Application_driver' ) ) ) ) );

Finally, add database credentials to the $PROJECT/config/autoload/local.php configuration file, as shown in Listing 14:

Listing 14. Adding database credentials


<?php return array( // ... 'doctrine' => array( 'connection' => array( 'orm_default' => array( 'driverClass' => 'Doctrine\DBAL\Driver\PDOMySql\Driver', 'params' => array( 'host' 'port' 'user' 'password' 'dbname' ) ) ) ) ); => => => => => 'localhost', '3306', 'root', 'guessme', 'appdata',

Be sure to update the database credentials in Listing 14 to reflect those of your database server host.

Generating Doctrine entities


You're now ready to generate Doctrine entities that you can use within your action controllers. You can generate these entities directly from the database through the command-line tool. You must update them manually to account for existing table relationships. To generate the entities from the database, open your command console. Change to the $PROJECT/vendor/bin/ directory and run the commands in Listing 15. (If necessary, change the path to your PHP interpreter.)
Use Doctrine with the Zend Framework Page 15 of 21

developerWorks

ibm.com/developerWorks/

Listing 15. Generating Doctrine entities from the database


doctrine-module orm:convert-mapping --namespace=Application\Entity\ --from-database annotation module\Application\src doctrine-module orm:generate-entities --generate-annotations="true" --generate-methods="true" module\Application\src

The first command in Listing 15 produces annotated Article and Publisher entities that are based on the existing database schema. The second command updates these entities to add setter and getter methods. The generated entities are stored in the $PROJECT/module/Application/src/ Application/Entity/ directory, as shown in Figure 8:

Figure 8. Autogenerated Doctrine entities

Updating relationship information


In the example scenario, many Articles might be published by a single Publisher, and so Article has a many-to-one relationship with Publisher. Manually add the ManyToOne relationship between Article and Publisher to the $PROJECT/module/Application/src/Application/Entity/ Article.php class by updating it with the annotation shown in Listing 16:

Listing 16. Updating the entities' relationship information


<?php namespace Application\Entity; use Doctrine\ORM\Mapping as ORM; /** * Application\Entity\Article * * @ORM\Table(name="article") * @ORM\Entity */ class Article { /* other annotations */ /** * @var integer $publisher *

Use Doctrine with the Zend Framework

Page 16 of 21

ibm.com/developerWorks/

developerWorks

* @ORM\ManyToOne(targetEntity="Publisher", fetch="EAGER") * @ORM\JoinColumn(name="publisher", referencedColumnName="id") */ private $publisher; /* other annotations and methods */ }

Now you can begin to use these entities in the application code.

Using Doctrine in Zend Framework 2.x controllers


Save the code in Listing 17, which lists the articles and publishers using Doctrine, to $PROJECT/ module/Application/src/Application/Controller/ArticleController.php:

Listing 17. Generating a list of articles and publishers


namespace Application\Controller; use Zend\Mvc\Controller\AbstractActionController; use Zend\View\Model\ViewModel; class ArticleController extends AbstractActionController { public function indexAction() { $em = $this->getServiceLocator() ->get('doctrine.entitymanager.orm_default'); $articles = $em->getRepository('\Application\Entity\Article')->findAll(); return new ViewModel(array('articles' => $articles)); } }

Listing 17 contains an ArticleController whose indexAction() is responsible for generating a list of articles and publishers. First, the getServiceLocator() method obtains an instance of the Doctrine entity manager, and then the entity manager's findAll() method retrieves a collection of Articles. This collection is then passed on to the view script at $PROJECT/module/Application/ src/view/application/article/index.phtml, which extracts the necessary information from it using getter methods. Listing 18 shows the view script:

Listing 18. Index action view script


<h2>Articles</h2> <ol> <?php foreach($articles as $article): ?> <li> <a href="<?php echo $article->getUrl(); ?>"> <?php echo $article->getTitle(); ?></a> <br/> <?php echo $article->getDate()->format('d M Y'); ?> | <?php echo $article->getPublisher()->getName(); ?><br/> </li> <?php endforeach; ?> </ol>

You also must add the new controller to the invokables array within $PROJECT/module/ Application/config/module.config.php, as shown in Listing 19:
Use Doctrine with the Zend Framework Page 17 of 21

developerWorks

ibm.com/developerWorks/

Listing 19. Adding the new controller to the invokables array


<?php return array( // other options 'controllers' => array( 'invokables' => array( 'Application\Controller\Index' => 'Application\Controller\IndexController', 'Application\Controller\Article' => 'Application\Controller\ArticleController' ), ), );

Now, browse to the URL http://example.localhost/application/article/index, and you should see output like that shown in Figure 9. (The output is a numbered list of three articles and shows the title, publish date, and website of each article.)

Figure 9. Listing records with Doctrine

In a similar vein, you can write a createAction() that reads article data from a web form and persists it to the database as a new record. Listing 20 offers an example implementation:

Listing 20. Create action


<?php namespace Application\Controller; use Zend\Mvc\Controller\AbstractActionController; use Zend\View\Model\ViewModel; class ArticleController extends AbstractActionController

Use Doctrine with the Zend Framework

Page 18 of 21

ibm.com/developerWorks/

developerWorks

{ public function createAction() { $form = new \Application\Form\ArticleCreate(); $request = $this->getRequest(); if ($request->isPost()) { $a = new \Application\InputFilter\Article(); $form->setInputFilter($a->getInputFilter()); $form->setData($request->getPost()); if ($form->isValid()) { $data = $form->getData(); $sl = $this->getServiceLocator(); $em = $sl->get('doctrine.entitymanager.orm_default'); $article = new \Application\Entity\Article; $article->setTitle($data['title']); $article->setUrl($data['url']); $publisher = $em->getRepository('\Application\Entity\Publisher') ->find($data['publisher']); $article->setPublisher($publisher); $date = new \DateTime($data['date']); $article->setDate($date); $em->persist($article); $em->flush(); $this->flashMessenger()->addMessage('Your submission has been accepted as item #' . $article->getId() . '.'); } } return new ViewModel(array('form' => $form)); } }

Listing 20 reads and validates the input that is provided through the web form. The code then uses the service locator to retrieve the Doctrine entity manager and initialize a new Article entity. The entity's setter methods set various properties from the form input. The resulting object is then written to the database by using the entity manager's persist() and flush() methods. Also, you can easily write methods to update, delete, and search articles, using techniques similar to the methods shown in the previous listings.

Conclusion
As this article demonstrated, you can add the power of Doctrine to a Zend Framework 1.x or 2.x application. Getting the two pieces to talk to each other is a somewhat complex task. But the effort is well worth it, because you can use all of Doctrine's ORM capabilities to perform advanced data manipulation from within a Zend Framework application. What are you waiting for? Get Doctrine and your favourite Zend Framework flavour, and put them to work.

Use Doctrine with the Zend Framework

Page 19 of 21

developerWorks

ibm.com/developerWorks/

Resources
Learn Zend Framework: Learn more about Zend at the official website: Read the community blogs. Take advantage of the Zend Framework 1.x Quickstart and Getting Started with Zend Framework 2. Access the full documentation. Learn how to contribute to the Zend Framework codebase. Doctrine: Visit the Doctrine project website. Bisna: Visit the Bisna site. Unit Testing Doctrine 2 Entities: View this video to see some examples of Bisna integration with the Zend Framework in action. Visit the developerWorks Open source technical topic for extensive how-to information, tools, and project updates to help you develop with open source technologies and use them with IBM's products. More articles by this author (Vikram Vaswani, developerWorks, August 2007-current): Read articles about XML, Google APIs, and other technologies. Get products and technologies Zend Framework: Download the Zend Framework. Doctrine: Download the Doctrine ORM tool. Bisna: Download the Bisna integration for Zend Framework 1.x. Doctrine ORM module for Zend Framework 2.x: Download the module. Composer: Download the Composer dependency manager. Innovate your next open source development project with IBM trial software, available for download or on DVD.

Discuss Get involved in the developerWorks community. Connect with other developerWorks users while you explore the developer-driven blogs, forums, groups, and wikis.

Use Doctrine with the Zend Framework

Page 20 of 21

ibm.com/developerWorks/

developerWorks

About the author


Vikram Vaswani Vikram Vaswani is the founder and CEO of Melonfire, a consulting services firm with special expertise in open source tools and technologies. He is also the author of the books Zend Framework: A Beginners Guide and PHP: A Beginner's Guide.

Copyright IBM Corporation 2013 (www.ibm.com/legal/copytrade.shtml) Trademarks (www.ibm.com/developerworks/ibm/trademarks/)

Use Doctrine with the Zend Framework

Page 21 of 21

S-ar putea să vă placă și