Robert Speer Web Development: Symfony, PHP, Wordpress, Business Analysis

Symfony refactor of the Zend Quick Start Tutorial


Digg!
Dzone

Learning Zend Framework and getting a repetitive stress injury doing it

Edit: please see Matthew Weier O’Phinney’s (the current project lead for Zend Framework) response in the comments, there are some exciting things comming for ZF

My friends & colleagues have used Zend Framework (ZF) for a while, and I do my best to avoid it and use the Symfony PHP framework.  Initially I was open to learning ZF, I was just curious why people liked it.  The more questions I asked, the more I realized there were no good answers other than standards for standards sake, and variations on the Sunk Cost Fallacy.  If pressed I was told that I had to give Zend Framework a chance because it is a younger framework than Symfony, (um no).  Some of the developers had even written a library to add on to Zend Framework to make it more usable, it contained features that were already in Symfony.  IMHO, writing code to help a framework catch up is an excellent reason to switch to another framework.

This last week I was finally forced to use ZF, my rebellious use of Symfony only served to annoy the other developers, and had the potential to increase maintenance costs.  It seemed like a reasonable request, and all those developers couldn’t be wrong could they?

Well yes they are.  I work with some great people whose feelings I don’t wish to hurt, but I would estimate that Zend Framework projects cost between 20 to 40 hours more for projects that run around ~400 hour plus. With agency rates what they are that could turn in to 6 or 7 thousand dollars of added costs. Assuming requirements for user authentication and backend CRUD’s.  These numbers will vary widely from project to project.

From a quick comparison of the Symfony Case Studies and the Zend Framework Case studies I would expect this efficiency gap to continue to increase.  A couple of Zend Framework‘s case study subjects have already failed: QEDWikiPokerRoom.com, and anyone who’s been unfortunate enough to have to customize Magento likely regrets the experience.   Symfony’s case studies are large successful projects you may have heard of:  DailyMotion, Yahoo! Answers, Delicious, & Yahoo! Bookmarks.  To be fair I’ve seen some really nice Zend Framework apps, I’ve just seen more interesting and larger Symfony projects.

A Quick Comparison

To present as fair a comparison as possible I have rewritten the Zend Framework Quick Start as a Symfony app. I also used Symfony 1.2 with the Doctrine ORM, both of which I’ve not used before, as my projects have been in Symfony 1 or 1.1 and the Propel ORM so far.

I’ve formatted this more as a timeline of events rather than a tutorial, however the full Symfony app source is available HERE.  To drop it on your web server you will have to change the path to Symfony in config/ProjectConfiguration.class.php, I had it running through WAMP on my local machine.

sfZendQuickStart Post
9:15am – 9:30am set up symfony app
9:30am -9:38am skip a bunch of Zend configs and translate layout to sf
9:40am – 9:43am generated controller & view, skipping autoloading in the bootstrap file
9:43am – 10:06am set up database
wrote schema.yml to define guestbook table
setup database connection string:
php symfony configure:database –name=doctrine –class=sfDoctrineDatabase “mysql:host=localhost;dbname=guestbook” username password
building model  (10:06am – 10:20am)
php symfony doctrine:build-model (GSS)
php symfony doctrine:build-sql   (generates the sql)
php symfony doctrine:insert-sql  (putst the sql in the db)
skipping the build database stuff, symfony does that for us
Listing out all guestbook entries in view 10:20am – 10:35am (got distraced with doctrine, I usually use propel)
Generating form classes (10:48am)
configuring to remove created at from view
unset( $this['created_at'], $this['updated_at'] );
random interruptions by wife….
writing view layer (11 am)
writing controller for saving  (11:15am)
Setting up captcha
installing form extra plugin:
php symfony plugin:install sfFormExtraPlugin
apparently I can’t type, kept putting the api keys in wrong , fancy reCaPTCHA complete (11:51am)
Double checked ZF Quick Start to make sure I did not forget anything
done (11:54am),
~2hrs 39 min
with distractions, a mySQL db, and a decent captcha
under 150 lines of me-written code code, including html I C&P’d from the zend tutorial
this means much less fumble finger type mistakes
The only config files I touched were
config/ProjectConfiguration.class.php to use Doctrine instead of propel automagically
config/doctrine/schema.yml to define the db tables
config databases.yml was set up from the command line so you be the judge on that one
Zend
Bootstrap file configuration
appliation.ini configuration
the zf tutorial expects you to write around 515 lines of code to do the same thing
that’s from the tutorial text not the well commented source code.

This also serves to document how I wasted a perfectly wonderful summer morning, *sigh*.

I did change some things around, I used MySQL because I’m not familiar with sqLite and, I used reCaptcha instead of a captcha similar to the tutorials.  I think these add difficulty, and are fair changes.

  1. 9:15am – 9:30am set up symfony app
  2. 9:30am -9:38am skip a bunch of Zend configs and translating layout to sf
  3. 9:40am – 9:43am generated controller & view, skipping autoloading in the bootstrap file
  4. 9:43am – 10:06am set up database
    1. wrote schema.yml to define guestbook table
    1. setup database connection string:
      1. php symfony configure:database –name=doctrine –class=sfDoctrineDatabase “mysql:host=localhost;dbname=guestbook” username password
    1. 10:06am – 10:20am building model
      1. php symfony doctrine:build-model (Getters, Setters & Stuff or GSS)
      2. php symfony doctrine:build-sql   (generates the sql)
      3. php symfony doctrine:insert-sql  (inserts the sql into the db)
      4. skipping the build database script, symfony does that for us
  5. 10:20am – 10:35am Listing out all guestbook entries in view  (got distracted with doctrine, I usually use propel)
  6. 10:48 am Generating form classes
    1. configuring to remove created at from view
      1. unset( $this['created_at'], $this['updated_at'] );
  7. random interruptions by wife….
  8. 11 am writing view layer
  9. 11:15am writing controller for saving
  10. Setting up captcha
    1. installing form extra plugin
      1. php symfony plugin:install sfFormExtraPlugin
      2. I can’t type, kept putting the api keys in wrong , fancy reCaPTCHA complete (11:51am)
  11. Double checked ZF Quick Start to make sure I did not forget anything
  12. 11:54am done

Development Highlights:

Symfony:

  • under 150 lines of me-written code, including html I C&P’d from the zend tutorial
    • this means much less fumble finger type mistakes
  • ~2hrs 39 min to complete from httpd.conf setup to form submission.
    • with distractions, a mySQL db, and a reCaptcha
    • I’ve clearly spent more time complaining about Zend Framework than it would take to complete the mini app in Symfony
  • The only config files I touched were
    • config/ProjectConfiguration.class.php to use Doctrine instead of propel auto-magically
    • config/doctrine/schema.yml to define the db tables
    • config databases.yml was set up from the command line so you be the judge on that one

Zend:

  • Configuration done in:
    • Bootstrap file configuration
    • appliation.ini configuration
  • the zf tutorial expects you to write around 515 lines of code to do the same thing as Symfony
    • that’s from the tutorial text not the well commented source code.
  • Also there promise of a “30-minute tour” can’t mean that you can program it in 30 minutes

Conclusions

Zend Framework is not bad, compared to using plain PHP there are some significant efficiency gains to be made.  However, when compared with Symfony and other frameworks, like Django & Rails,  it’s missing key features found in modern Web Development frameworks.  The tutorial I described here demonstrated the efficiency issues of not having code generation for the Model layer.  Two other key features are generated CRUD’s for backend site management, and a full MVC plugins like Symfony, Rails, & Django all have.

The long term ramifications of not having plugins and generated code accelerating your project are corners cut on quality, reduced features, scaling problems, and less competitive bids.  The lack of robust plugins in Zend also means that it will never be able have as many features as frameworks that do have Plugins.  Not having code generation means that developers are spending too much time writing mindless getter’s, setter’s, & data grids and not enough time focusing on the core features of the project, or worse they are making compromises in quality to make deadlines.

I don’t believe that the Zend Framework is so far behind that it can’t catch up.  In certain areas it’s actually ahead of the game, however those areas tend to not be fascinating edge cases I get to use every so often, and not features I use on every site every day.  My suggestion for Zend is use the Model layer examples available (Active Record,  SQLAlchemy, Doctrine) and  do something like that.  Doctrine already integrates well with Zend, maybe that would be a good option.  Then start generating admin interfaces or CRUD‘s, this is huge, I find all kinds of ways to use these things to add value to my projects with a little typing on the command line.  Finally Plugins, the most important consideration when reviewing a framework or CMS.  The quantity and quality of plugins demonstrates the quality of the development tool.  It also means that there are developers out there that care about the tool outside of the core team.

If you are interested in learning more about Symfony there are excellent tutorials like the Jobeet example app, a cookbook, a guide book, a reference book, an API, and more on the symfony doc’s page.

Be Sociable, Share!
  • This an excellent post. As the author of a free ZF book in progress I’m about to add a chapter that pretty much tells people to use Zend_Db on tiny projects – and otherwise ignore it. ZF badly needs an ORM solution and a proper code generator for an admin backend. In their absense people get the idea they are not needed which is very obviously insane. Hopefully some future proposals make the cut like the DataMapper one.

  • I agree there are some noteworthy gaps in ZF and I’m sorry that the Zend_Db layer has basically stagnated. They don’t have anyone on the project who really knows database issues.

    One comment to be fair: I wouldn’t blame ZF for Magento. Magento makes heavy use of an SQL antipattern called Entity-Attribute-Value (EAV), which has a lot more to do with difficulty of using it than their choice of ZF.

  • Bill Karwin: Johnathan Wage (http://www.jwage.com) is employed by Sensio Labs to maintain Doctrine. Couldn’t hurt to he’d like to assist on the Zend side as well.

    Symfony certainly not bashful about using good code or ideas from other frameworks, so it may work out well.

  • I also wanted to point out that the form classes are also generated in symfony.

    I just had to unset a few fields and add validation for the email.

    http://www.symfony-project.org/forms/1_2/en/

  • It is very easy to use Doctrine with Zend Framework, along with the code generation for the model(s). I recently switched from Symfony to ZF, mainly because of it being more loosely coupled – which also means you can’t really compare it to Symfony.

    • Kurt Ward: Thanks for commenting!

      I’m aware that Doctrine can be used with ZF, I actually link to a tutorial on how to integrate Doctrine into Zend in this post.

      I do however think that it’s totally fair to compare Zend Framework to Symfony. You using one for a replacement for the other is a perfect example of why they are fit for comparison.

      Beyond the model layer I also pointed out that Zend Framework needs a admin generator and real plugins similar to Rails, Django, & Symfony. In a later comment I added form class generation. I could go on and talk about things like the web debug toolbar, and how cool sfGuard is, but I don’t want to seem like too much of a fanboy ;)

      Symfony is also becoming increasingly more loosely coupled, a good example of this is: http://components.symfony-project.org.

  • Check out ZFDebug for an equiv. debug bar, there is also a plugin for ZFDebug to incorporate Doctrine. There are things I miss using Zend Framework vs. Symfony, I just find it easier to do things other than MVC based webapps with Zend. It’s also nice to just be able to use it as a component library in an existing/legacy app.

    • Kurt Ward: I saw the debug bar, it looks good. I think you’re hitting on interesting topic when you bring up using ZF as a component library.

      I think I’ve heard some rumblings about this somewhere on the internet. Combining all the great classes available from several of the PHP frameworks out there as well as PEAR & phpclasses.org it is becoming increasingly easier to roll your own framework customized for a given application.

      A framework that is almost all plugins & external libraries would be very compelling to me. Assuming getting them to play nicely was a reasonable amount effort.

  • I am currently leading the Zend Entity + DataMapper proposals with the help of others which at the first stage aims to implement an ORM with the DataMapper pattern and on top of this aims to use the metadata to generate form templates and such using Zend_Tool Providers.

    I currently aim to get an incubator/first look version completed for the 1.10 release, which is a very likely outcome since the component is developed test-driven, has over 500 tests and is fully functioning for 70% of the query needs.

    So you should keep an eye on future Zend Framework improvements in this area. :-)

  • I am using Zend framework. They have very good library and ready class so for novice programmer it is the best choice. Symfony is advance than ZF. But developer do not get much snippets for Symfony. Also for customization simfony gets less point than ZF.

    At last, I appreciate for this article. It is really helps to those who wants to start to learn new framework.

  • Hi. I am using symfony in commercial projects for more then 2 years (everyday). I started with version 1.0. Then I developed commercial projects using v. 1.1 so I was prepared to use 1.2 which is the most advanced version available so far. (Everyone who has not moved from 1.0 -> 1.2 should do it as soon as possible).

    I have to say that learning process is quite long but once you finished – you will be happy that you have invested your time in something what is worth it.
    Today good framework is a must. There is nothing to stop you to build whatever you want if you are using symfony.

    Highly recommended framework but not to novice in PHP. First you need to know how to do 1000s things…. by handcoding ;)
    Documentation is great anyway.

    Without symfony I rather change my web language to different. But now I love it again.

    Happy coding :)

  • Great post, I love symfony and I also think it’s the best one out there wright now, If you want to know why I think it is the best framework to start with read: http://tr.im/wyWR

  • Surprisingly, I’m just seeing this article for the first time today. Full disclosure: I’m the current project lead for Zend Framework.

    I understand many of your points. I also want to point out that many of your criticisms are unfairly tainted by your familiarity with Symfony — if you are fluent in one framework, you’ll of course be able to do things faster and easier with it than with a framework with which you are unfamiliar. You blast the ZF 30-minute tour as not meaning you can write the code in 30 minutes (true, but that was never a claim), and go on to show how you developed equivalent functionality in symfony in just over 2 hours — which is approximately how long it took a fluent ZF developer to write the ZF quickstart (the code written took around 2 hours, most of which was spent on testing the DataMapper displayed in the examples).

    I also agree fully with you that we need more work with model generation and CRUD screens. This is one area where we definitely lag. That said, I also think we pose one advantage over other frameworks in precisely this area, because we do not explicitly tie these operations to the database. I personally feel this is an area where many frameworks “get it wrong”, as tying models to the database prevents developers from looking at the bigger picture where data persistence may be happening on a middle tier or via a 3rd party web service, and the database is nowhere present in the web-facing application. If and when we offer model and CRUD generation, one requirement will be that the models are de-coupled from the actual data persistence to allow for these increasintly common situations. (With the release of Zend_Tool, CRUD generation will be coming sooner rather than later.)

    Bill Karwin notes that we do not have anyone on the ZF team actively maintaining Zend_Db. This, actually, is not true, and those users of Zend_Db will have noticed a ton of fixes and improvements in the past 2 months (most of which released with 1.9.0). Ralph Schindler, one of our engineers, is also not shy about reaching out to known DB experts to get opinions and guidance for those areas in which he is less familiar.

    On the ORM front, as beberlei noted, he is working on an Entity/DataMapper framework for ZF that has many similarities to Doctrine2. Additionally, I am in discussions with ZF contributors and Doctrine developers regarding the possibility of offering more formal ties between our two projects — which would give ZF two choices for ORM functionality, and allow developers fluent with Doctrine to migrate to ZF very quickly and easily. (I myself have been using Doctrine fairly extensively with a number of projects recently, and enjoy the fact that it helps reduce the amount of custom code I need to write.) As part of these efforts, I hope to dedicate some time to form generation from entities — a task that, as you note, can also be tedious. This should not be terribly difficult, as most form metadata necessary will already be part of the entity definitions.

    Regarding plugins, one way in which ZF differs from other frameworks is that contributors tend to contribute their plugins back to the project, instead of offering them separately. This is in part due to the fact that we do not have a “forge” site (yet) for ZF where people can post their plugins, but also due to the fact that we encourage contributions to the project itself. As a result, I feel you overlooked the fact that we have many, many dozens (potentially hundreds) of plugins throughout the framework — look at the quantity of action helpers, validators, filters, decorators, adapters, and view helpers if you need proof.

    Thank you for taking the time to post this critique, and I urge you to keep evaluating ZF with each new minor release — and keep us honest by pointing out where we need improvement.

  • Matthew: I’m looking forward to see ZF’s changes in the future.

    And of course how the other frameworks respond, because competition and new ideas are going to make all frameworks better.

    Also if I was totally fair and objective this would not be the internet that we all know and love ;)

  • Sorry for my english, but i think symfony and ZF are equivalent. This posts remember the troll between emacs and vi.

    Finally, i agree with Robert Speer the competition and new ideas are going to make all frameworks better.

  • I am glad that you wrote this article since I was beginning to feel like I was in “The Emperor’s New Clothes” and noone would speak out. I have used Symfony for a couple of years and I am very fast and proficient with it. The last few months I have been trying to migrate some projects over to the Zend Framework and I am pulling my hair out with frustration. It is like I went from driving a Corvette to riding a bike. And that 30 minute “Quickstart Guide” is only quick if you understand ZF. I think that the Zend Framework is trying to become the next J2EE :P.

  • “I am glad that you wrote this article since I was beginning to feel like I was in “The Emperor’s New Clothes” and noone would speak out.”

    I have to totally agree with Ethan here. Everyone seems to have ****-on for ZF. I dont hate it but its definitely not as polished and lacks a lot of the tools SF has. Id say the two are equally as complex. But SF’s out of the box dev tools make this a lot less intimidating/time draining when you first get started. Allowing for a good working pace on a real project as youre learning.

    My main complaints about Zend are:

    - .ini is the default config format – you can use XML but you have to set it up yourself, and there is no YAML support built in. To make matters worse there is no direct example of how to map things from ini to xml – granted its pretty straight forward but there are a couple gotchas.

    -Rampant use of complex array structures as arguments. Ok, ill admit in a lot of place this is to support DI, and is totally beneficial but in some places it is not at all desireable… the Zend url view helper comes to mind. Its ok to parse out of strings for simple things…

    - Its a use at will framework – which is great if you need to keep things small and/or have small objectives. However there is no built in tooling feature to help you manage what you actually need to deploy. This is made worse by the fact that that they seem to include EVERYTHING in the core… Gdata, InfoCard, OpenId, etc.. They should be in ZendX, or there should be some kind of plugin system or build manager to exclude the cruft without manual tracking.

    - Along with the previous their package layout makes it impossible to svn:external into a project the packages you want. You either external all of the standard and/or extras library or you put what you need directly in SVN. So annoying… but hey at least they arent using GIT without an SVN mirror.

  • Excellent blog post Robert. However, when I went to download sfZendQuickStart.zip I discovered the link is broken. :(

    Any chance you could correct it?

  • Excelent. Thanks Rob.