Deprecated: This code uses an old version of Doctrine and Zend Framework, there is now an semi-official way of integrating Doctrine and Zend Framework, see the announcement of the zf-doctrine project and checkout my plugin for ZFDebug to have access to the Doctrine Profiler: http://github.com/danceric/zfdebugdoctrine

I’ve talked about that before on this blog. Using Doctrine 1.1 with ZendFramework 1.8 and using both with ZFDebug. Now things will only get better as both project will officially play nice together. Here’s the announcement on the Zend Framework mailing list.

This is some pretty good news, the other good news is that you don’t have to wait until the integration is ready to start playing with both. I’ve been testing out the alpha3 release of Doctrine 1.2 and I’m pleased to see that it’s really PEAR friendly, which make it a breeze to use it with the Zend Framework (that wasn’t as easy with Doctrine 1.1).

you can follow along with the code on github of my demo app: github.com/danceric/zfdebugdoctrine

First thing, the base doctrine class have been moved from /Doctrine.php to /Doctrine/Core.php, which mean that the Zend autoloader can now find it without special config/hack, just add Doctrine_ as a namespace and let ZF do the magic. This can be done in your application.ini with this single line

autoloaderNamespaces[] = "Doctrine_"

Second thing, which is the nice part, is that there is now a PEAR Style Model Loading and Generation, which means that the Doctrine cli can now generate models that can be autoloaded by ZF too. To generate your model from a yaml file (in ./doctrine/schema/schema.yaml`, you can run the doctrine-cli script like this

php ./scripts/doctrine-cli generate-models-yaml

and they will be generated in ./application/models. Note the generate_models_options array of options that define how the model classes will be named. Now, If you wish, you can move the models around to put them in a module by prefixing the classname with modulename_ as you would normally do. If you love spending more time in php land, you can build your model directly in php instead of the yaml file, just by extending the Doctrine_Record class. Check out the Doctrine Documentation, it’s really easy to do.

One thing to keep in mind, just as your web pages read the environment setting (APPLICATION_ENV) from ./public/.htaccess or ./public/index.php, the command line script for doctrine have to be set to use the expected environment too (3rd line of the script).

Once again, here’s the link to the working application that use Doctrine 1.2alpha3, Zend Framework 1.9.5 and ZFDebug 1.5

github.com/danceric/zfdebugdoctrine

Short ‘n Sweet Version

  • start a ZF project
  • add the doctrine namespace to your autoloader in your application.ini

    autoloaderNamespaces[] = "Doctrine_"
  • connect to a database in your boostrap as

    $manager = Doctrine_Manager::getInstance();
    $manager->openConnection('your-connection-dsn');
  • Create your models in the application/models folder by having class that extends Doctrine_Record

    class Model_Base_Post extends Doctrine_Record
    {
        public function setTableDefinition()
        {
            $this->setTableName('post');
            $this->hasColumn('id', 'integer', 4, array(
                 'primary' => true,
                 'autoincrement' => true,
                 'type' => 'integer',
                 'length' => '4',
            ));
            $this->hasColumn('content', 'string');
        }
     
        public function setUp()
        {
            parent::setUp();
            $timestampable0 = new Doctrine_Template_Timestampable();
            $this->actAs($timestampable0);
        }
    } 
Posted in php.

27 thoughts on “Doctrine 1.2 is Zend Framework friendly

  1. thanks for your article, the integration works great, almost.

    migrations are not working anymore. is that normal? i noticed several posts on the internet where people were having problems with migrations or create-sql or any other doctrine cli command which should change the database. but unfortunately i didn’t find any solution to this problem

    is there anybody else experiencing the same problem, and knows how to fix it?

    any feedback on the issue would be appreciated, currently i’m stuck here with zf 1.9.5 an doctrine 1.2

  2. Just starting out with ZF and Doctrine, this is just what I was looking for.

    A quick note for all, when using methods from the Doctrine base class, eg. Doctrine::getTable(), in 1.2 (and beyond I’d expect) you’ll need to do Doctrine_Core::getTable(). Just a heads up.

  3. Anyone else having bother using create-tables or build-all-reload etc. Using the example on github it looks like all is fine with it, but the generate-sql creates an empty file and nothing is created on the actual DB? Anyone else? Im using ZF 1.9.5 and Doctrine 1.2

  4. @Dkwad thanks for your feedback, I’ve just noticed some errors in my post, first there is a typo in the command (missing ‘s’ in the comand’)

    php ./scripts/doctrine-cli generate-models-yaml
    

    but the main thing missing in my code is that the ./library folder should contain the vendor folder from Doctrine 1.2. It’s new in Doctrine 1.2, the external yaml parser. I’ll update github once I get home.

    With this vendor folder in place, I have successfully ran these commands:

    php ./script/doctrine-cli generate-models-yaml
    php ./scripts/doctrine-cli create-db
    php ./scripts/doctrine-cli create-tables
    php ./scripts/doctrine-cli generate-sql
    
  5. @danceric, Appreciate you having another look And was the database updated as expected with model data. The missing ‘s’ didnt catch me, in fact I had never even noticed.

    I had the vendor directory in the library folder as well, when I run the commands create-tables and generate-sql the CLI tells me they ran successfully but there is no change in the DB.

    The strange thing is I can create and drop the DB using the CLI and generate models as expected, the paths are correct and so is the dsn. But I cannot create the tables and the generate sql file is always created empty.

  6. Been playing more with this, I was trying to generate the models via yaml. When I create the models extending Doctrine_record it works. Will test migrations etc as well. Any idea why it didnt work the other way round now?

    Again thanks for the help… I’m getting there, slowly :)

  7. I must confess that I’m clueless now. I have deleted the model classes, the database and the generated sql. I can use this command:

    php ./scripts/doctrine-cli build-all-load

    and everything get created as expected, (but I don’t have any output from doctrine telling me that it worked, the exact opposite of your scenario hehe).

    with a fresh copy I’ve used these commands with success

    build-all
    build-all-load
    build-all-reload
    create-db
    create-tables
    generate-models-yaml
    generate-sql
    generate-yaml-db
    

    btw, there is a change needed in the fixture file (in github now), need to change Post to Model_Post

  8. Works fine, except that update statements are not displayed? I can see the transaction begin and end statement, but the updates themselves are missing in ZFDebug?

    Is this the usual behaviour or is something wrong with my configuration? Is there a debug level to configure?

    best regards, el al.

  9. Update: ZFDebug prints Update Statements when using DQL update method to build the query and execute() method to execute it.

    If you are using the save method like:

    $user = new User();
    $user->Email->address = 'foobar@email.com';
    $user->save();
    
    (see doctrine documentation for details and example)

    then the update is not printed by ZFDebug. Any idea?

  10. Update: ZFDebug prints Update Statements when using DQL update method to build the query and execute() method to execute it.

    If you are using the save method like: $user = new User(); $user->Email->address = ‘jonwage@gmail.com’; $user->save(); (see doctrine documentation for details and example)

    then the update is not printed by ZFDebug. Any idea??

  11. thanks for pointing the ‘Update’ bug, I’ll take a look at it this week end and report back here (btw, I have edited the email in the previous comment code sample)

  12. PHP 5.3.0, ZendFramework 1.9.5, Doctrine 1.2.0-beta3 and ZFDebug 1.5, this code:

            $foo = new Model_Post();
            $foo->content = 'this will be an insert';
            $foo->save();
            
            $foo->content = 'this one is an update';
            $foo->save();
    

    output this in the debug toolbar:

    zfdebug screenshot

  13. Hello,

    thank you for your answer. Looks like NOT to be a bug, looks like a failure in firefox. My example works in other Browsers, but not in firefox.

    The reason is, that firefox does – for any reason – 2 requests on the controller (haven’t seen them in firebug yet, but it MUST be a second request, as the mysql log demonstrates when calling the page with firefox and with other browsers).

    Doctrine checks if the record is dirty. Now, with ff the result for the second request is NOT dirty, because the first request did the update with the same values already one second before.

    Sorry for that, it is not a problem of your plug in, but probably of my browser config and/or webserver config!

  14. hi, me again …:

    I added this code to the index action of the index controller in your code example:

    $writer = new Zend_Log_Writer_Stream(APPLICATION_PATH.’/debuglog.txt’); $logger = new Zend_Log($writer); $logger->info(var_export($_SERVER, true));

    If I call the page with http://danceric:8080/ with firefox 3.5.5 (and all extensions disabled), there are two requests are written to the debug file. If I call the page with opare, id or chrome I have exactly one request, as expected. I removed the database calls in the index action of your code example, but that did not change anything.

    If I remove the line $frontController->registerPlugin($debug); in the _initZFDebug() method of your bootstrap file, firefox does only one request!

    At last, i can not find the reason why firefox does this second request, when zfdebug is enabled with the doctrine plugin!?

    Any idea?

    I am currently using the same versions as you does (doctrine, zfdebug), except the php version, its php5.28. I will have a try with php5.3….

    perplexity!

  15. I’ve recently downloaded Doctrine 1.2 and started to poke around with generating classes PEAR Style. I have a question regarding the setup that you demonstrate in the ‘zfdebugdoctrine’ example. You apparently have your classPrefix set to ‘Model_’ during generation, and the doctrine ‘models’ directory is APPLICATION_PATH . ‘/’ . models. From my experimentation Doctrine will generate the Post class at the following path:

    {APPLICATION_PATH}/models/Model/Post.php

    How do you avoid this? How are you getting doctrine to add the ‘Model_’ prefix and not created a ‘Model’ sub directory? Are you just generating in another directory and copying the result over to tohe APP_PATH/model directory? Is there some setting that I am missing?

    Thx, D

  16. Hi Daniel, when you set classPrefix to Model_, you also have to set classPrefixFiles to false if you don’t want an extra Model folder to be created. Hope this help.

  17. From the Doctrine 1.2 documentation -

    classPrefixFiles – true – Whether or not to use the class prefix for the generated file names as well.

    I think I’ll have to suggest that the Doctrine people clarify this, because I did not interpret this description as meaning that the prefix directories would be omitted. Oh well.

    Thanks for the help, I’m a happy guy now. :)

  18. Have you guys tried using YAML to generate models that extend from others? I seem to be experiencing some autoloading issues with one such example:

    Foto_Decoration_Text:
       inheritance:
          extends: Foto_Decoration
          type: simple
       columns:
          image_id:
             type: integer
          text:
             type: string(255)
          font:
             type: string(255)
          font_size:
             type: integer
    

    ‘Model_Foto_Decoration’ not found in /Users/chris/Desktop/coding/zend_exp/zf_doctrine/application/models/Base/Foto/Decoration/Image.php

    Any thoughts?

  19. Pingback: ZF, Doctrine and Unit Tests » elink media blog

  20. Hello,

    I was able to get my local zf 1.9.6 / doctrine 1.2.1 project working by following your zfdebugdoctrine example.

    I notice tho when I add

    $manager->setAttribute(Doctrine_Core::ATTR_MODEL_LOADING, Doctrine_Core::MODEL_LOADING_CONSERVATIVE);

    to _initDoctrine() inside my bootstrap, when I try do a build-all-reload, the database nolonger gets populated.

    Has anyone experienced this and know how to fix this?

  21. I have the exact problem as Kevin. I did change it to MODEL_LOADING_AGGRESIVE and build-all-reload worked fine, creating the tables and all. But since _initDoctrine is shared by both online and cli, I cant leave it at AGRESSIVE.

    Any clues?

  22. Pingback: Zend Framework Blog » Blog Archive » Aus den Zend Framework Blogs (Spezial: Doctrine und Zend Framework)

Comments are closed.