I actually wrote this over two months ago, but never got around to publishing it. It’s an account, written in real time, of my first experience with the Zend Framework.
Preface
Zend recently released the stable version of it’s framework, 1.0.0 (and shortly after that 1.0.1). The company I work for is planning a long term port of their web apps to the framework, with a short term goal of integrating some of the individual components, such as zend_db and zend_cache.
I have five years of PHP experience. Originally doing almost everything procedurally, then moving to a custom framework pieced together from Smarty, Fusebox and my own database model class. Around a year and a half ago I took up CakePHP and have been using it ever since. I’ve done a bunch of Cake sites and although I’m comfortable with it now, I remember struggling with it at first. Part of that was the normal learning curve and part was the early version I was using.
Now that you know a bit about my background here’s my first experience with the Zend Framework. I’m going in cold here. I’ve read a lot about the framework, but nothing really on how to use it.
7:30PM
I’ve got a four pack of Red Bull, the baby is in bed, and my wife is doing homework for her grad course. I have should have a few hours of uninterrupted time, so let’s rock this thing. I can’t wait to create some “Hello Worlds.” Just try and stop me.
7:35
I went to Zend’s site and downloaded the framework (http://framework.zend.com/download). I went with the zip, since I do my development on windows w/ XAMPP. The zip is 4.65MB. Cake’s latest 1.2 alpha is only 634kb. That’s four megs of extra goodness.
7:40
I just read the INSTALL.txt file. I’m going to re-print the entire installation section right here. You ready?
The Zend Framework requires no special installation steps. Simply get a copy of the framework and ensure that the /library directory is in your PHP include_path.
That’s it.
I make a folder called zend in my xampp/htdocs and throw the whole thing in there.
I’m so excited I can’t even figure out which of the 17 php.ini files that comes with XAMPP to edit.
7:50
It’s /apache/bin/php.ini for anyone who cares.
My include now looks like this:
include_path = ".;C:\\Program Files\\xampp\\php\\pear\\;C:\\Program Files\\xampp\\htdocs\\zend\\library"
Booo: Pear. Yeaaah: Zend
8:00
Hmmm…I pointed my browser at the zend folder and I get a dir listing. Where the hell is index.php? There are some demos and they work, but I was expecting the Cake like welcome page.
To the docs!
8:05
The reference guide looks nice and seems pretty thorough, but I’m can’t seem to find the quick start section. Off to Google.
8:10
The first result for “zend framework tutorial” is for a pre-release version. Commentators say not to use it. I guess “Because this tutorial is published online, I’ll update it as the framework evolves, so that it remains relevant as long as possible.” really means “the internet is for static content, when scientists invent a way to to make changes I will update this document”. I shouldn’t knock on Shiflet. He’s a PHP superstar and kind of looks like Doogie Howser (note: The pic changed to look less Doogie like since I originally wrote this), so even if he got into a horrible PHP security related accident and lost all his programming knowledge he would still have that going for him…unless the accident scarred his face.
8:35
I’m on my second Red Bull. Somehow this one spilled into a glass of ice and vodka. Crazy how these things happen.
The comments from the Shiflet article lead me to this and this.
I’m a bit scared off by the 9 part IBM article, even though they produce some good stuff. Plus it’s all dated 2006, so I’m not sure if it’ll apply to the 1.0.1 release. If only there was a way to update the content of something once it was put online…if only…
The other thing that bothers me about IBM’s stuff is they categorize some parts as “Articles” and others as “Tutorial”. Seriously, parts 1,4,6,7,9 are articles. Parts 2,3,5,8 are tutorials. What’s going on over there? I remember this causing me headaches when I was trying to find all five parts of their Cakephp artorial…or is it tuticle?
9:00
Turns out its up to you to create your own index.php, called the bootstrap file in Zend lingo. You also have to manually create the dirs for your app. Akrabat’s PDF has a dir layout, but I can’t tell if it’s Zend required layout, Zend recommend layout or Akrabat’s “this is my layout - don’t question it” layout.
Either way, I’m not crazy about it. It has the everything in the webroot, then adds htaccess files to deny access. Plus the RewriteRule redirects everything to index.php, then requires another .htaccess to turn off rewrite for images/js/css.
9:30
Eh…The luster is wearing off. I’m two hours in and I haven’t done any code.
9:35
I understand now why some people are calling this the Zend Component Library.
9:45
One of the things I like about Cake is that it promotes best practices. I’ve seen some complain that it is rigid and you have to do things the Cake way. But I don’t mind because a) the Cake way is well thought out and b) it makes easy to pick up someone else’s work.
9:55
I’m convinced someone could make a living buying and selling Red Bull. The price fluctuates more than the price of gold. Somedays it’ll be $2 a can, $7 for a 4 pack. Other days it’s $3.75 a can and $12 plus 10% of all future earnings for the four pack. Don’t even get me started on the new 12oz monster cans they have now.
10:05
I can’t get my brain around not putting a closing PHP tag (?>) at the end of a file. I know it doesn’t “matter” and it prevents you from accidentally leaving whitespace at the end of a file and prematurely sending output to the browser.
Zend’s coding guidelines even expressly prohibit the end tag:
“For files that contain only PHP code, the closing tag (”?>”) is never permitted. It is not required by PHP. Not including it prevents trailing whitespace from being accidentally injected into the output.”
When did this become such a problem? I think it happened to me once and I fixed it in about 3 seconds. This is the programming equivalent to peanut allergies. Who ever heard of such a thing 20 years ago (3 years in PHP’s case) and now all of sudden it’s more widespread than…resisting Paris Hilton joke…screw it…it’s more widespread then Paris Hilton at a night vision camera convention. See I’m not above making three year old pop culture references. I should remove the link from my site to this blog before I never get another freelance job again.
10:15
If don’t you think all this rambling isn’t a pathetic cover while I feverishly read AK’s tutorial then go ahead and keep believing that.
10:25
Ok the tutorial is nice and all, but in the end it’s really just a generic CRUD app that I could generate with Cake’s bake script in about 10 minutes.
Here’s my favorite part:
“It shouldn’t have escaped your notice that addAction() and editAction() are very similar and
that the add and edit templates are identical. Some refactoring is in order! I’ve left it as an exercise for you, dear reader…”
So basically he’s saying: “This is one way to do it, but it’s not a very good way. There’s a much better way and I know it. I could tell it to you and make this tutorial really kick ass, but instead I’m going to leave it to you to figure out.” Thanks.
10:30
For some reason Zend has a bunch of web service classes - not that I’m against this, but it seems odd that they would be part of the core framework. Plus I’d rather have a really nice index.php/htaccess that would work on 99% of the apps. Hell I don’t even know what half these services are. Lucene, Reflection, Strikeiron? These have to be sponsored right? That has to be how Zend is making money off this thing.
10:33
I’ve decided against doing a really boring CRUD app as my first Zend project. If they’re going to include all these random web services I mine as well use one.
10:35
Lucene is “a general purpose text search engine written entirely in PHP 5″. Kind of cool. RSStalker is the closest thing I have to a content heavy site, but I’m not sure Lucene would do much there. NEXT!
10:38
I have to cut back on these Red Bulls - I’m not seeing straight. Apparently Lucene and Reflection aren’t services. I read “Zend_Search_Lucene” and “Zend_Server_Reflection” as “Zend_Service_…”
10:40
I was thinking of doing something with Akismet. Like a text area where people can put in anything then run it through Akismet to see how spammy it is. Kind of like a challenge to see who can produce the spammiest text. In the end I think that would be abusing a cool free service, plus it looks like they only return true/false and not a score.
10:43
Hey Zend manual team. Add a “overflow: auto;” to your pre.programming style. Otherwise your code samples look a mess if I shrink my browser.
10:46
Audioscrobbler is kind of cool. They provide a ton of interfaces to their music info. I remember like 5 years ago I wanted to do a site called onesong.com. The premise was if someone told you about a band and you wanted to find their best song to give them a try you could go to this site and find the top rated (by the users) song. Audioscrobble has a artistGetTopTracks call. I’m sure this has been done a million times by now. Still I consider this a candidate.
10:51
StrikeIron is intesesting. I’m surprised I’ve never heard of them. They “offer hundreds of commercial data services (”Data as a Service”) such as Online Sales Tax, Currency Rates, Red Bull Open Market Prices, Stock Quotes, Geocodes, Global Address Verification, Yellow/White Pages, MapQuest Driving Directions, Dun & Bradstreet Business Credit Checks, and much, much more.”
Come on. There is no way they didn’t pay to be included. The “and much, much more.” is such generic marketing speak. Can’t you just imagine a cheesy over excited guy in a question mark suit reading that last paragraph on a late night infomerical. Anyway, StrikeIron offer some interesting choices and the first 10k requests/month are free.
10:54
I’m going with AudioScrobbler, but not the onesong thing.
A couple of weekends ago I was down in Baltimore with some friends from high school and college. We we’re chatting about music at the O’s/Sox game and one of my friends mentioned there was a new The Receiving End of Sirens CD. I didn’t even know it was going to be released. I’m sure there are a bunch of sites that provide RSS feeds of new album releases, but you still have to scan through the list to find the bands you want. You could use Yahoo! Pipes to filter the list, but I’d rather just be able to get feeds from the bands I want.
Be back…Going to Google for 2 minutes and see if this exists.
10:57
Back. Nothing I could find. I’m going to do this RSStalker style, meaning each band gets its own feed, so if you want to track a 10 bands you’ll need 10 feeds. I could have the user make an account and pick the bands they like, then generate one feed. But then I have to deal with the whole user account thing. I like this way better because someone can just unsubscribe from their aggregator and not have to remember their login to remove a band.
11:00
Hmm…it appears AudioScrobble doesn’t even require an account, so I may actually be able to get his online tonight.
This is a bit worriesome: “Do not exceed one request per second to ws.audioscrobbler.com without prior
arrangement, it will result in your IP being banned.”
This means I’ll have to do a backend script to handle the updates, rather than just updating at the time the feed is requested. Even if I cached the feed, Bloglines requests a bunch of updates at once, so if more than one cache needs to be refreshed I could violate that policy.
Also if someone else is using the service on my shared server it could cause problems. No real way to tell this though, so I’ll just hope I’m the only one (and that my shared IP isn’t already banned).
11:25
Looks like the Zend docs are already out of date. “setArtist” function doesn’t exist. Unless it’s overloaded somewhere, but I’m getting a “Fatal error: Call to undefined method Zend_Service_Audioscrobbler::setArtist()”. I guess it was replaced with the genereic “set” method. Out of curiosity I’m going to check version 1.0.0.
11:28
Nope, not there either.
11:30
Putting together the request and getting back data was pretty easy, except the list of albums is missing TREOS latest release. I guess I’m only getting “Top” albums, not all, but “The Earth Sings Mi Fa Mi” is listed as a top album on the website. A search for Metallica returns 50 hits, but the TREOS only 4, missing the latest album. Seems like the web service data isn’t as complete as the website.
I plow ahead anyway.
11:35
I’m not crazy about using the term “incubator” for trial/in development projects. I feel like they’re waiting to burst out the belly of their host and reek havoc on a ship full of PHP developers. And my wife said the mechanized loader suit was a waste of money. HA!
11:45
I just did a quick AppTable that extends Zend_Db_Table that catches inserts and automatically adds the created and modified dates, like Cake.
I’m not crazy about the fetch syntax:
$row = $band->fetchRow('name = "$key_name"');
Feels like I’m still writing SQL. I prefer Cake’s array approach.
11:48
I also miss being able to set DEBUG to 2 and having all the SQL dumped at the bottom of the page. Zend’s fetch row ($band->fetchRow(’name = “$key_name”‘);) is returning null. It would be nice to see the query that is being run.
11:50
Yes I’m a moron. I was using ‘ instead of “, which means $key_name wasn’t getting replaced with the actual value. I’ll still argue if I could have seen the query I would have known the problem right away.
11:55
Having separate insert/update db calls is kind of annoying too. A generic save, which figures out the right syntax would be nice. AppTable to the rescue!
12:05
I’m sorry, but Zend’s documentation sucks. I know Cake gets crapped on all the time for it’s poor docs, but they are way better then Zend’s in my opinion. Zend’s docs are all style. They look nice, but once you start looking for how to do something even the simplest of things it’s not there. Take http://framework.zend.com/manual/en/zend.db.table.html#zend.db.table.insert.key-auto for example. How do I get the id of the newly inserted row? We’re talking about one line of code, but in multiple paragraphs about auto-incrementing keys, sequences and natural keys they don’t answer that simple question.
While I’m on the topic the API sucks too. I practically live in Cake’s API. That’s my home on the corner of Cache and Auth streets. The blue one with the white shutters.
Cakes API smokes Zends API - no argument. Where is the search? Where is the link bringing you right to the code? You can argue that Zend API is using phpDocumenter, so it’s limited to that functionality? I think that’s a poor excuse and makes me wonder how phpDocumenter skated by for so long.
Despite my grievances, this app is coming together quickly.
12:30
By the way the answer to my above rant about how to get the auto id: the return value. It’s the return value.
12:40
Somewhat often the AudioScrobler service fails to respond causing an error to be thrown. Which works well until the catch block tries to do a getStatus on a non object and a fatal error occurs. Oh well I guess that’s the risk you take using beta software. Whats that? Zend is production ready you say?
12:44
There’s actually a band called “asdf” with a self-titled album.
SimpleXMLElement Object
(
[name] => asdf
[mbid] => SimpleXMLElement Object
(
)
[reach] => 4
[url] => http://www.last.fm/music/ASDF/asdf
[image] => SimpleXMLElement Object
(
[large] => http://cdbaby.name/g/i/girldown.jpg
[medium] => http://cdbaby.name/g/i/girldown.jpg
[small] => http://cdbaby.name/g/i/girldown.jpg
)
)
I just spent 15 minutes trying to debug why this, since I was expecting the search to not return anything.
12:50
I spent a few minutes trying to figure out how to relate tables and decided to move on. Even if I figured it out all the examples were still using two queries rather than one query with a join
1:25AM
Once I got rolling this thing actually came together pretty quickly. It probably has a bunch of bugs and I never got around to doing an update script. Because of this I’m not really comfortable putting it online. I’ll probably just zip it and include the code with this post.
1:40AM
I’m officially exhausted and declaring this done. Here’s the zip of the code. There is no documentation, it is thoroughly buggy and it was written in a five hour binge by someone trying to learn a framework and probably includes code that would make a seasoned Zend professional give up PHP forever and take up Java or ASP.
Epilogue - Two Months Later
Re-reading this it’s clear I soured on Zend by the end. To be honest, if it was the only thing out there I would probably stick with it and eventually depend on it. I remember when I was first forcing myself to learn CSS. I hated it. I kept thinking how easy it would be to switch back to table-based layouts. But I knew it was better so I stuck with it and now can’t image going back.
With Zend I’m not convinced it is better then the alternatives, namely CakePHP. It’s really just a matter of preference and if Zend had gotten to me first, maybe that would be my #1. In the end it doesn’t really matter. Zend, Cake, Symfony, CodeIgnitor…they’re all a trabillion times better then slopped together procedural code.
Popularity: 53% [?]










I’m working on a new design for my personal site,
On my old blog I kept a subdomain that I called the “sandbox”. It was a standard CakePHP installation, where I could post plugins or code that I intended to release. Since the old blog is deprecated, I wanted to port the sandbox to this blog, basically give it a design that matched. This is normally pretty straightforward, so to up the degree of difficulty I decided to keep the old design as well and automatically switch the layout based the domain.
Follow!