Archive for July, 2006

RewriteRouter and Zend_Config play together

Tuesday, July 18th, 2006

While getting the hang of the Zend_Controller_RewriteRouter, which is now included in Zend Framework 0.1.5, I was adding the routes in my index.php (bootstrap) file and wondered if there was any way of storing them elsewhere. It is possible to loop over Zend_Controller_RewriteRouter::addRoutes() but the method I will describe here is based on some recent updates to Zend_Controller_RewriteRouter by its author Michael Minicki.

The point of RewriteRouter is to map urls, like ingredients.com.au/recipe/tomato_sambal, to whatever controller, action and parameters needed without having to use external (and often painful!) methods like mod_rewrite.

For the sake of this article I’ll use a relatively simple URL…

ingredients.com.au/articles/cooking/

First setup some routes in a config file “routes.php”. Note that this does require the latest version of the RewriteRouter which needs to be checked out from the subversion repository

$config['routes']['articles'] = 
new Zend_Controller_Router_Route('articles/:category', 
array('category' => 'all', 
       'controller' => 'articles', 
       'action'      => 'index' ), 
       array('category' => '[a-z_]+') );

This establishes a route called “articles” that will respond to any url of the form “/articles/whatever” with the colon in :category indicating that it is an url variable that can be recovered through Zend_Controller_Action::_getParam( ‘category’ ). The controller and action indexes make the action “indexAction” in the controller file “ArticlesController.php” the final target. To cover cases where there is no category specified the default setting “all” is given. For extra assurance :category has to be a string containing only lower case letters and underscores as indicated by the final requirements array.

Next load them into the bootstrap file using Zend_Config_Array:

$routes = new Zend_Config( 
        Zend_Config_Array::load( 
       '../application/configuration/routes.php', 'routes' ) );

Then create the RewriteRouter object and pass it the $routes…

$router = new Zend_Controller_RewriteRouter;
$router->addRoutes( $routes );

All that is needed now is to pass the $router to the front controller…

$controller = Zend_Controller_Front::getInstance();
$controller->setRouter( $router );

That’s it, now the routes are nicely stored outside of the bootstrap file and with the rest of the domain files.

Further Reading

Aside from the manual pages mentioned I can’t close without pointing to an actual recipe for tomato sambal !!

Endnote

I should also mention that it’s well worth getting involved with the development of the framework even if you can only do so in a small way. After a relatively short discussion via the issue tracker about having some means to load routes in one hit, Michael Minicki had implemented one (thanks Michael).

Mr Dizzy, Getters/Setters and Constructors

Monday, July 17th, 2006

Mr Dizzy“Mr Dizzy was to be quite honest, not very clever.”

One day, while refactoring a web application from procedural to object oriented code, Mr Dizzy decided to use constructors in a way that anyone in Cleverland would have pointed out was really not very clever.

While Mr Dizzy was building his user class he decided that it would be useful to have getPermissions() and getOrganisations() methods. These methods needed to make a query or more to the database to get the information they needed.

Mr Dizzy thought it might be a good idea to have the setters for these methods in a constructor so that when he needed a User object it would have gathered all the necessary information and was ready to go, so, he added setPermissions() and setOrganisations() methods.

“Great”, thought Mr Dizzy, and he proceeded to use his new user object. His idea seemed to be working well so he decided to use the same idea in his Organisation class so it could also get its own permissions on call. “Even better”, thought Mr Dizzy, “I can’t wait to show this to the other programmers in Cleverland”.

Before taking a trip to Cleverland, Mr Dizzy decided to finish off some code to allow him to show a list of users. This list included using many instances of his newly built user class.

Can you guess what happened?

Of course, every time a new user object was created so too was a new organisation object and so too was a new permissions object and all of these objects made database queries. Before long hundreds of queries had been made to the database, all hidden away nicely in constructors.

Luckily for Mr Dizzy he had done his usual trick of missing the last bus to Cleverland and had also recently installed the Zend_Db_Profiler which showed just how silly he had been before anyone else could see.

From that day on Mr Dizzy knew to be very careful when deciding what to do within constructors.

Obvious, but necessary disclaimer

Surprised as you may be, Roger Hargreaves, the original author of the excellent Mr Men series of children’s books, did not in fact author any of the above. Nor, unfortunately, was it narrated by Arthur Lowe, but I’d recommend that if you know his voice then you imagine him doing so.

Mr Dizzy is obviously copyright and I probably shouldn’t be messing with the classics, so if there are any copyright objections then I’m happy to alter this tribute. I do recommend that even if you don’t have kids you should own at least one Mr Men or Little Miss book if only for the great graphics!

Finally, I, of course, would never do something as silly as Mr Dizzy!

Collaboration Markup

Thursday, July 6th, 2006

I work in plain text a lot, from using Markdown or more specifically PHP Markdown on this WordPress setup and elsewhere, as well as doing HTML markup and programming PHP. It is therefore not surprising that this article on Collaboration Made Simple with Bracket Notation caught my eye (linked via Lifehacker).

It’s a simple but clever idea that eschews a specific software solution for collaborative content editing in favour of notations in plain text. I don’t want to steal anyone away from reading the article but I did want to note a simple way of remembering their idea…

[delete][replace with][comment]

…so if we take the text…

The Bat in the Hat

…and apply some collaborative revision markup…

The [Bat][Cat][less sinister?!] in the Hat

…it would be revised to…

The Cat in the Hat

It’s a useful trick to to remember e.g., for passing edits around in text format via IM or Email. Whether I use it or not is another thing but I certainly like the inventive use of simple tools.

Zend Frameworking underwater.com.au

Tuesday, July 4th, 2006

Now that the host for underwater.com.au has upgraded to PHP5 I’m working on migrating it to use the Zend Framework. I thought it may be interesting to run through a few of the reasons I’ve chosen to do so especially while the framework is in such an early stage of development.

“Underware”

The engine, code-named “Underware”, that underwater.com.au currently runs on is built almost entirely (excluding a few additional class files) from my own code. Developed, via several projects, over the course of about five years from a modified version of the PHP e-Commerce application Freetrade and the FreeEnergy structure (Actually, it’s interesting to look back over that FreeEnergy article to see how it’s almost a Model-View-Controller structure), Underware is now more object-oriented, more MVC’ed and more woven with design patterns than its early incarnations, however it still has loose threads.

Why grow your own?

Considering the amount of freely-available, open-source, PHP code it seems idiotic to be doing it all yourself. Sadly, the number of applications available is no indication of their quality, nor whether they will play nicely together, a point taken up by Clay Loveless in his Stop Writing Loner Applications post.

At every stage of Underware’s development I looked at pre-existing solutions, hoping to find one that wouldn’t force me to duplicate components I already had, such as user management. It wasn’t necessarily that I had better code, more that what I did have was only what I needed. Besides, I knew as I worked on it the code quality would also improve. Inevitably, after spending many unbillable hours pouring through different solutions I’d look at the clock and think “I could have spent those hours moving forward and coding a solution”!

Pros of doing it all yourself

  • You only build, debug and support what you need.
  • You know all the code.
  • You learn a lot.

Cons of doing it all yourself

  • You have to build and support every bit of code and unless you build it it’s not just going to appear from somewhere.
  • You have to document it all.
  • You have to spend time researching solutions to every issue, including system level ones that are not directly providing solutions for your clients.

Thankfully the increasing amount of frameworks available (i.e. rather than finished applications) combined with the growing object-oriented’ness of PHP mean it’s less of an either or situation.

So why Zend Framework?

Honestly, I think because it feels right and I say that not to be facetious, but partly because I see so many lengthy arguments for and against such and such framework as if one or the other holds the golden key. Part of the reason I went back to my roots was to show the influences on my way of structuring web applications and if you’re interested enough to look into them you may see some similarities. For me the Zend Framework not only fits the way I’m currently working but moves it forward, tying up some of the aforementioned loose threads for example.

More pragmatically there are factors like the fact that my clients can worry less about being so totally dependant on me for every facet of their applications; I can benefit from all the external input to the framework itself; I can focus on solving client needs more and system level needs less and not to be ignored is the Zend part of the framework which for me puts at least some stamp of longevity and consistency on the code base.

Some further Underware influences

Some current Zend Framework reading