|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
April 27, 2008 MotivationI 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 IncubationZend 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 baseThe 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 Framework is completely miswiredZend_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 ConventionGood 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 featuresZend 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:
WTH is wrong with these people? Buggy CodeSome 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 DocumentationThe 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?
Profit of OOP By: Greg Donald <gdonald at gmail dot com> Posted: 5 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. Readed and thinking By: kometo <kometo at gmail dot com> Posted: 4 months ago something you wrote is correct as my opinion.
A step in the right direction? By: Bruno Girin <brunogirin at gmail dot com> Posted: 4 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: 4 months ago Bruno,
PHP MVC frameworks By: Bruno Girin <brunogirin at gmail dot com> Posted: 4 months ago Greg,
I don't know.. By: Greg Donald <gdonald at gmail dot com> Posted: 4 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: 3 months ago Greg,
another title By: benny <benny at whitewashing dot de> Posted: 3 months ago It probably took you lots of time to rant about this why not use the time more productively?
Doctrine for the model By: desfrenes <desfrenes at gmail dot com> Posted: 2 months ago "You can add whatever validation you need in accessor methods."
Dear desfrenes, By: Greg Donald <gdonald at gmail dot com> Posted: 2 months 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.
use at will By: desfrenes <desfrenes at gmail dot com> Posted: 2 months ago "Why would I care about validating data when "accessing" it?"
Dear desfrenes, By: Greg Donald <gdonald at gmail dot com> Posted: 1 month 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. i'm too dumb to think of an actual title for my comment By: desfrenes <desfrenes at gmail dot com> Posted: 1 month ago Now I see what Matthew Ratzloff meant.
Dear desfrenes, By: Greg Donald <gdonald at gmail dot com> Posted: 1 month ago I refuted every single one of Matt's points here:
|
|
||||||||||||||||||||||
|
|||||||||||||||||||||||
Angry RoR fun
By: Tom <waza at delfi dot lt>
Posted: 5 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