Blog » Blog Entry

Zend Framework, "Web 2.0 Framework" My Ass!

April 27, 2008


Motivation

I am writing this to inform web developers of my experience with Zend Framework so they can choose wisely when shopping for a MVC "framework" to use with their next "big project". I feel Zend Framework is a lost cause and a complete waste of time to learn and to use. I hope to help other developers take notice of the many issues I found with it so they will be more inclined to consider other, better alternatives.

I will go ahead and concede the fact that I'm a huge fan of Ruby on Rails. I've been using it since before it was even version 1.0. It is the poster-child for what a MVC framework should provide. Ruby on Rails embraces most modern software design principles. It has a huge following and a great future ahead.

So be warned, once you use Ruby on Rails for more than a project or two, anything else will likely seem broken or incomplete. And this is exactly the state of affairs with Zend Framework: very broken, and very, very incomplete.


My experience and background:

I am 36 years old and a "career programmer". I've been programming in one language or another, for over 24 years. My first programming language was BASIC on an Apple IIe in 1984. Since then I've worked with most everything I could get my hands on, some of my favorites include: Pascal, LISP, Scheme, C, C++, D, and even C#, although I do not care for its owners.

Most of my current programming expertise exists in the web development realm. I know Ruby, Python, and PHP fluently, and I use them all regularly. I maintain several popular open source PHP projects and have built a number of significant Ruby on Rails projects using MySQL, PostgreSQL, and Oracle. I still claim a basic working knowledge of Perl and did use it quite a bit in the mid to late 90's, but not so much anymore. I'm a big fan of Parrot and can't wait for an "official" Perl6 release.

I currently work at a local medical university in the biotech field. I'm currently tasked with developing genetics research applications in Ruby on Rails using Oracle on the backend.

I hold certifications in both PHP and MySQL.


About Zend Framework:

As any experienced web developer may have noticed, Zend, "The PHP Company", has decided to put together a code base they have titled "Zend Framework". In a nutshell, I find Zend Framework offensive and a very poor effort coming from a company with as much PHP influence as Zend.

Most of the components in Zend Framework are not even "loosely" coupled, much less aware of each other's existence. A few components do work with some others, but overall most components don't talk to each without much effort on the part of the developer.

I was recently informed that Zend Framework is a "glue" framework. That's seems a bit pointless in the day and age of web services and RSS feeds. A stand-alone site can already very easily talk to another web site and does in no way require it's own internals to be "glued" together.

Zend Framework sets out to solve many non-problems and only creates additional object-oriented (OO) overhead along the way. If I've posted it once, I've posted it a dozen times: OO, for the sake of OO, is pointless. If you don't have a good reason to make something into an object, why bother?

At this point I will let you decide for yourself, based on technical merit and direct comparison, which "framework" is the better choice this day and time.


Missing Models:

Zend Framework doesn't have models. Until it does it can never compare to a true MVC framework such as Ruby on Rails or Django. Zend Framework instead has Zend_Db, which its authors seem to think is a model. I disagree. Here's what Wikipedia has to say about "models" in the context of the MVC design pattern:

The domain-specific representation of the information on which the
application operates. Domain logic adds meaning to raw data (e.g.,
calculating if today is the user's birthday, or the totals, taxes,
and shipping charges for shopping cart items).

Many applications use a persistent storage mechanism (such as a
database) to store data. MVC does not specifically mention the data
access layer because it is understood to be underneath or
encapsulated by the Model. 

Zend_Db is not domain specific and does in no way encapsulate data. Zend_Db is just a mechanism to provide SQL obfuscation. It doesn't validate data before storing it in the database, and clearly it doesn't hide the database layer underneath itself. Minus your own chosen database driver, it _is_ the database layer in Zend Framework.


Controllers and Views are NOT tightly coupled:

Zend Framework's connection from controller to view leaves much to be desired. One thing that bugs me in particular is that to set a variable in the controller one has to use this unwieldy syntax:

$this->view->foo = 'bar';

And then to use that same variable in the view, one must use this similarly unwieldy syntax:

$this->foo

PHP programmers might actually not find this sort of extra syntax offensive, but knowing many other languages and frameworks besides PHP and Zend Framework, I certainly do find it very offensive. Here's an example from Ruby on Rails:

To set a variable in a controller action:

@foo = 'bar'

To use that same variable in the view:

@foo

While a single instance of using the ugly Zend Framework way would probably not cause anyone a terrible amount of pain, working through a years-long enterprise project could easily send someone in for carpel-tunnel surgery and rehab.

The better PHP solution is quite simple, variable variables. One could easily bring all those unwieldy view variables into local scope with something as simple as this:

while( list( $k, $v ) = each( $this->view ) ) ${$k} = $v;

Only having to type $foo in the views would then be possible.


REST seems to be "away taking a nap"

In these docs:

http://framework.zend.com/manual/en/zend.rest.server.html

There is a require statement for My/Service/Class.php. But the docs don't mention what that Class.php file might look like. Am I to consult a crystal ball in such matters? And why do I have to provide my own class to the REST class? I was at first curious as to why there is no mention of a single REST verb in the docs, but then I realize it's because Zend Framework expects me to provide all of that support myself, making the fancy Zend_Rest_Server "class wrapper" class nothing but OO overhead.

So, like any unknowing developer might do, I asked the Zend Framework community for some direction. Here's the reply I got:

The way this works is that you attach your service class to the
REST server and let it handle all requests from there.  And the
methods if the class have to be statics, that's all. I know
there is no real example, but I think it works along the lines
of Zend_XmlRpc_Server (haven't tried it though).

No real example? I see.

Another reply was someone trying to help me understand what REST is:

Zend_Rest_Client is the component for addressing Rest-ful web services, see:

http://en.wikipedia.org/wiki/Web_service...

In that case, the component you're looking for is Zend_Soap, which is still in incubation.

Sorry, but them's the breaks.

I don't recall asking what REST is; I have already been using it for nearly two years in Ruby on Rails. He didn't know that so I let it go.

And then finally, someone else decides to help me realize what I already thought. The current best way to consume a web service using Zend Framework is actually the usual "PHP way" using SOAPClient and simplexml.

Why exactly do I need Zend Framework again? Obviously not to build a Web 2.0 site that consumes web services.


A thought about Incubation

Zend Framework labels its unfinished software as being in "incubation". Much like Zend Framework itself, I suppose the usual word "beta", which is often used to depict the state of an unfinished software project, doesn't provide sufficient overhead. I guess being an Apache developer wanna-be is better than nothing.


Where's the Javascript?

Zend Framework contains no direct integration with any of the currently popular Javascript libraries. To use something like Scriptaculous or JQuery, one must integrate it directly.

When a framework is touted as a "Web 2.0" framework, expectations are raised, at least for me. When a framework is released as version 1.5.1, I have significant expectations for certain things to be there and to be working already.

One of the main expectations I had before beginning to learn Zend Framework was Javascript integration. I don't want to have to go out and get Javascript libraries myself; I can already do that without ever touching a framework. I want my Javascript integrated and as far as possible I want my framework to write my Javascript code around the models and forms for me.

For example using Ruby on Rails, this is how to detect an incoming Ajax request:

if request.xhr?; end

Similar methods also exist for get? and post? requests.

This sort of request handling lets me make any single action in my controller work for get, post, or xhr depending on the end user's browser capabilities. To process the request, a template is automatically rendered based on the request itself. You don't have to specify the template unless you want to, "convention over configuration" shines here. If the request is get?, you get a regular html template. If it's an xhr request, a Javascript template is rendered instead. The Javascript template can do anything to the DOM using very small syntax such as:

page.replace 'foo', :partial => 'bar'

This code, for example, replaces something in the DOM with an ID of 'foo' with a different HTML template named 'bar'. This Ruby code represents direct calls into the Scriptaculous Javascript library. Notice how no actual Javascript is required to be written by the developer? The framework writes the Javascript for you. You only have to know Ruby, a single language, which really helps speed things along in development, as your brain isn't constantly shifting from one language context to another.

Zend Framework has nothing like that. Just search the Zend Framework docs for "Ajax" or "Javascript". You will be presented with docs for controllers where no Javascript code examples appear.


Lack of experienced developer base

The Zend Framework authors would have you believe Zend Framework is already hugely popular and that it currently has a large following of users and so forth. The size of an open source project's community is after all a sign of its possible future direction and uptake.

While discussing lack of technical merit for specific Zend Framework features it was stated to me there were "thousands" of PHP developers subscribed to the various Zend mailing lists. I find that incredibly difficult to believe since there are only about 10-15 posts per week on all the lists combined. I know this because I was, for about two weeks, subscribed to every single list Zend Framework has available. I'm not sure why "little Willy" would need to tell such an obvious lie like that, I guess it helps him feel better in some weird way.

The Ruby on Rails mailing list, has 13,934 members at the time of this writing:

http://groups.google.com/group/rubyonrails-talk

And that number of members produces about 200 posts per day.

The Django mailing list has 8,749 members at the time of this writing:

http://groups.google.com/group/django-users

And that number of members produces about 70-100 posts per day.

As is commonly said, you do the math.

Zend List versus Rails List
Clearly Zend Framework does NOT have "thousands" of subscribed PHP developers on its lists. If I'm wrong and it does, they are all being very quiet, not discussing much of anything at all. But then what's to discuss with a framework that's missing so many obvious features.



Zend Framework is completely miswired

Zend_Validate isn't aware of Zend_Db whatsoever. At a minimum it should live inside or at least be tightly coupled with the model code. There is no better place to protect data entry than right _before_ it gets entered. The way Zend Framework works breaks the DRY software development principle:

http://en.wikipedia.org/wiki/DRY

Zend Framework forces me to validate each and every form on a given website no matter how many times the site might deal with the same Zend_Db instance. Code reuse in that respect is simply not possible.

Zend Framework forms lack all knowledge of Zend_Db models. Zend Framework misses an excellent opportunity to use the meta data from the models to more easily create forms. Here's an example for how Ruby on Rails does it:

http://api.rubyonrails.com/classes/ActionView/Helpers...

Zend Framework docs show Zend_Validate* and friends connecting to forms rather than to models. This mixing of business logic into the view layer is an abomination to anyone who is familiar with MVC design principles.

Zend Framework is so miswired it's comical.


Configuration over Convention

Good MVC frameworks follow a simple software design principle called "Convention Over Configuration". Here's a URL in case you haven't heard of it:

http://en.wikipedia.org/wiki/Convention_over_Configuration

Zend Framework doesn't embrace it and even goes so far as to break normal PHP functionality along the way. Here an example where normally you only have to pass three parameters to hook to a local Oracle XE install:

db.username = mydbuser
db.password = changeme
db.dbname   = 127.0.0.1/XE

$db = new Zend_Db_Adapter_Pdo_Oci( array(
 'username' => $config->db->username,
 'password' => $config->db->password,
 'dbname'   => $config->db->dbname
));

That doesn't work. In Zend Framework it has to be (more):

[testing]
db.username = zend
db.password = zend
db.dbname   = XE
db.host     = 127.0.0.1
db.port     = 1521

$db = new Zend_Db_Adapter_Pdo_Oci( array(
  'username' => $config->db->username,
  'password' => $config->db->password,
  'dbname'   => $config->db->dbname,
  'host'     => $config->db->host,
  'port'     => $config->db->port,
  'options'  => $options
));

Zend Framework forces you to add the default Oracle port 1521, which has been the same for as long as I can remember, and also define the host, which will always be 127.0.0.1 in Oracle XE. What exactly is the point of that?

Note that PHP's oci_connect() function does not require a port number. Zend Framework equals more pain than gain.


Pointless features

Zend Framework is chocked-full of useless features. It seems like they want to wrap everything in an OO layer, no matter how unnecessary it may be. For example, what is to be gained by using Zend_Registry? It seems to me I could more easily just use the existing PHP $GLOBALS array or even $GLOBALS[ 'registry' ] if I needed a namespace.

Here are some examples:

Zend_Registry::set( 'index', $value );

versus

$GLOBALS[ 'index' ] = $value;

Or

$value = Zend_Registry::get( 'index' );

versus

$value = $GLOBALS[ 'index' ];

Or

$registry = Zend_Registry::getInstance();

foreach( $registry as $index => $value )
{
   echo "Registry index $index contains:\n";
   var_dump( $value );
}

versus

foreach( $GLOBALS[ 'registry' ] as $index => $value )
{
   echo "Registry index $index contains:\n";
   var_dump( $value );
}

I really don't see the point in typing more rather than less. Zend Framework's entire plan seems to be something similar to:

  1. Wrap existing PHP functionality with an OO layer.
  2. Pretend it helps the developer.
  3. Pretend the new "feature" doesn't create additional overhead.
  4. Profit?!?!

WTH is wrong with these people?


Buggy Code

Some context first: Oracle RDBMS likes things to be capitalized by default, field names in particular. Being the lazy developer I am, I don't really want to have to type field names in all caps all the time. So I set out to use Zend Framework's CASE_FOLDING option to make all of my database field names return in lowercase. It works in one direction, when you get the fields _from_ the database, but like most of Zend Framework, its components aren't aware of each other resulting in Zend_Db's from() method requiring uppercase field names:

$options = array( Zend_Db::CASE_FOLDING => Zend_Db::CASE_LOWER );

$db = new Zend_Db_Adapter_Pdo_Oci( array(
  'username' => $config->db->username,
  'password' => $config->db->password,
  'dbname'   => $config->db->dbname,
  'host'     => $config->db->host,
  'port'     => $config->db->port,
  'options'  => $options
));

This doesn't work:

$select->from( $stats, array( 'count' ) );

You have to do it this way:

$select->from( $stats, array( 'COUNT' ) );

I have no idea why they would think I would want my field names one case coming from the database but the other case when building up SQL for a query.

When I use Ruby on Rails with Oracle I don't ever deal with field names much, I deal with model attributes. Model attributes are always consistently lower case by default. Who would have guessed?


Misleading Documentation

The docs here:

http://framework.zend.com/manual/en/zend.rest.client.html

Show using this URL in the example:

http://framework.zend.com/rest

Which doesn't exist. It'd be nice if it did exist or the code just said "example.com". example.com is the usual address that appears in technical documentation and is obviously not to be expected to work.

But why not actually build the URL in a previous chapter then show using it immediately following. Is it too much to ask for some common sense when building documentation?

Tags: php, rubyonrails, zend

« Ubuntu 8.04 Hardy Heron First Impressions Only creationists don't understand why people laugh at creationists.. »

Angry RoR fun

By: Tom <waza at delfi dot lt>

Posted: 4 months ago

At some points perhaps you are right like stuff with JS ...
but things that you wrote here like :
" 1. Wrap existing PHP functionality with an OO layer.
2. Pretend it helps the developer.
3. Pretend the new "feature" doesn't create additional overhead.
4. Profit?!?!" <--

It makes me think that you just do not understand the profit of OOP :)
Sorry it's my opinion



Profit of OOP

By: Greg Donald <gdonald at gmail dot com>

Posted: 3 months ago

I do indeed understand the profit of OOP, I just don't find much of it to be had when using Zend Framework. Wrapping existing PHP functionality in an OO layer does not equal OOP profit. It causes more server load, forces one to learn a heavier syntax, and creates more code to maintain overall.

Anyone who thinks PHP is a "good" OO language clearly has no significant experience Ruby or Python. There is life beyond PHP.

Readed and thinking

By: kometo <kometo at gmail dot com>

Posted: 3 months ago

something you wrote is correct as my opinion.
like: Model layer

where is the correct place of validate ?This is the issue what I'm thinking hard.

A step in the right direction?

By: Bruno Girin <brunogirin at gmail dot com>

Posted: 2 months ago

Coming from J2EE and having tried RoR and Zend Framework, I agree with most of what you say. However, in situations where you have to build an application that is meant to be deployed with an ISP that only supports PHP, I find Zend Framework a step in the right direction compared to raw PHP. If you know of any better MVC PHP framework, I'd be really interested.

Plenty of options, hosting and MVCs

By: Greg Donald <gdonald at gmail dot com>

Posted: 2 months ago

Bruno,

There's no shortage of Ruby on Rails savvy web hosts:

http://www.railshosting.org/

Just because _your_ ISP may not support it doesn't mean it not being support very well otherwise.

And of course there are better PHP MVC frameworks than Zend Framework, have a look:

http://www.phpwact.org/php/mvc_frameworks

And notice how many are "modeled after Rails".

PHP MVC frameworks

By: Bruno Girin <brunogirin at gmail dot com>

Posted: 2 months ago

Greg,

Thanks for the link to that list of frameworks! Which one of those would you recommend? I've heard of Cake but not of any of the others.

Also, I agree that there are a lot of RoR savvy web hosts around but for the type of projects I work on I usually don't have the choice of the host. And more often than not, it's still PHP or nothing. Don't get me wrong: when I can work with a web host that supports RoR and PHP, it takes me a nanosecond to decide which one to use :-)

I don't know..

By: Greg Donald <gdonald at gmail dot com>

Posted: 2 months ago

I have two friends who speak highly of Code Igniter, but I've only glanced at it. I used Mojavi with much success, but that was 4 or 5 years ago. PHP just isn't a very good language to make a MVC framework out of. I mean, look at Zend, it doesn't even have a model component. PHP just isn't very meta-capable. Making it write code that writes code is next to impossible.

Titles should not be required...

By: Matthew Ratzloff <matt at builtfromsource dot com>

Posted: 2 months ago

Greg,

Ugh. I'm having flashbacks from my computer science days, when arrogant nerds with egos looked down on you if didn't use Linux for your desktop because it was unusable.

Can I tell you something? Know your audience. I am pretty open-minded but was immediately turned off by the level of vitriol in your rant.

Now, let me talk about the specific issues you raised.

1. Models. You can add whatever validation you need in accessor methods. There are differing opinions on database manipulation, however, and other implementations will come. There's an ActiveRecord proposal currently that depends on PHP 5.3.

2. Coupling. It's a different philosophy. I hate tight coupling. I prefer Merb to Rails; you would disagree.

3. Zend_Rest. You didn't raise the biggest issue of all with Zend_Rest, which is that it's not RESTful. I and others have argued against its inclusion in the framework, instead favoring a specialized Route specifically for REST.

There is a Zend_Soap. The unit tests are being finished up. It will be included in a future version.

4. JavaScript coupling. I wrote an entire blog post about this:

http://www.builtfromsource.com/2006/12/20/does-ajax-have-a-place-in-the-application-framework/

I don't think there's much value added by coupling PHP and JavaScript frameworks, but Zend apparently does, which is why they've announced a partnership with Dojo. There will be a variety of Dojo-specific tools and helpers included in the framework going forward.

5. Both projects you mention (Rails and Django) have existed longer than Zend Framework. Rails was the first real Web framework for Ruby, hence its popularity. Django is one of the few Web frameworks for Python (maybe 10, only two or three of which are popular). PHP being a Web language, it has easily a couple dozen Web frameworks, many of which have existed for years and are currently more mature and more popular. It's not a fair comparison.

Nor is it relevant. Framework choice is largely a matter of software architecture philosophy, and regardless of the fact that CakePHP is probably more popular, it does not match my philosophy.

6. Zend_Registry has other features that make it more useful than $GLOBALS.

7. The problem you found is an issue that should be corrected.

8. Straw man example aside, the documentation for Zend Framework is very good, and definitely much better than Rails (not hard to do).

Again, you prefer tightly-coupled frameworks. Many developers don't.

another title

By: benny <benny at whitewashing dot de>

Posted: 2 months ago

It probably took you lots of time to rant about this why not use the time more productively?

class Zend_View_Extended extends Zend_View_Abstract
{
protected function _run()
{
while( list( $k, $v ) = each( $this ) ) ${$k} = $v;

include func_get_arg(0);
}
}

class Zend_Controller_SuperAction extends Zend_Controller_Action
{

function __set($name, $value)
{
$this->view->{$name} = $value;
}
}

This solves all your problems (even using some of your code) of item 2.

$this->getRequest()->isXMLHTTPRequest() solves another one, writing Ajax Form Submits, POST or GET via a good library on your own takes exactly the same time than writting them for any View Helper, which actually just represents the same function call just in its respective language. So why bother about this topic?

Additionally most people get along better with one or the other javascript library, so I am quite happy to decide which one i can use with ZF. Extending the View Object with another "javascript" helper to wrap your favourite libraries functions into PHP would probably also take just a little bit.

Doctrine for the model

By: desfrenes <desfrenes at gmail dot com>

Posted: 3 weeks ago

"You can add whatever validation you need in accessor methods."

Yes, everything and its contrary is possible, however I agree that Zend Framework lacks automated model validation (see django as an example), which would prove very useful for most cases.

For this purpose may I suggest phpDoctrine for the model layer ?
It has model validation and constraints: http://www.phpdoctrine.org

Dear desfrenes,

By: Greg Donald <gdonald at gmail dot com>

Posted: 3 weeks ago

The data validation needs to go in the model. Why would I care about validating data when "accessing" it? At that point it's already in the database, it's already invalid. Data validation needs to happen _before_ the data goes in.

And last time I checked, Zend Framework doesn't even have a "model".

use at will

By: desfrenes <desfrenes at gmail dot com>

Posted: 3 weeks ago

"Why would I care about validating data when "accessing" it?"

By "accessors", I guess previous commenter meant "mutators". I'm sure none ever intended to validate/filter data in getters (sillly isn't it ?).

"And last time I checked, Zend Framework doesn't even have a "model".

True in the sense of a model as seen in Django or RoR, that's a bad point and you're right about it. that's why I pointed you to phpDoctrine which, if you needed it, fills the gap (and more) and is easy to integrate in ZF (that's 3 lines of code really).
ZF does have its shortcomings, however it is very flexible. You can say "Zend_Db_* sucks" and use any other ORM you like :-)

Other points:

"Where's the Javascript?"

Actually ZF has now dojo bundled, along with helpers à la RoR. Still, I think javascript helpers suck and I wouldn't use any framework feature integrating javascript. Why should framework A or B got me stuck with javascript framework X instead of Z ? I want to be able to chose which javascript library fits my needs (and this libary is always JQuery, not Prototype or Dojo ;-) )

ZF is a "use at will" framework with loosely coupled components (see how you can use any templating engine you like). Why should it be compared to RoR or Django ? I personaly use Django and ZF everyday but not for the same tasks.

It's all about the right tool for the right job. Do you think RoR is the best choice for any web application ? Then you really are a fan ;-)

Dear desfrenes,

By: Greg Donald <gdonald at gmail dot com>

Posted: 2 weeks ago

I'm not going to waste my time time trying to fill in the missing gaps in ZF when RoR is already complete. Same goes for Django, and it's brain-damaged "applications" setup.

RoR already supports every popular JS framework out there, including Dojo.. forcing you not to choose any single one, but instead allowing you to choose among many. If you don't use JS then you simply don't include it in your layout files.

Right tool for the job? That's the dumbest thing I've ever heard.. I've used Django and I've used ZF, and I've used RoR. Guess what? They all produce web pages in the end. They are the same tool trying to solve the same problems.

Anyone with half a brain will is usually smart enough to see that RoR is the best current choice for a MVC web framework. It's missing nothing and has everything. Call me a fan if you want, I couldn't care less.

i'm too dumb to think of an actual title for my comment

By: desfrenes <desfrenes at gmail dot com>

Posted: 2 weeks ago

Now I see what Matthew Ratzloff meant.

Good luck.

Dear desfrenes,

By: Greg Donald <gdonald at gmail dot com>

Posted: 2 weeks ago

I refuted every single one of Matt's points here:

http://destiney.com/blog/more-silly-zend-framework-idiocy

Read it, and learn just how broken and mis-wired your favorite framework is.

In the meantime, if you can't argue about ZF on it's technical merits, which are few and far between, then don't bother posting. Whining about some he-said bullshit is a waste of my time.

Add a comment:

Title:

Comment:

Name:

Email: