Modern Application Design - Part 1
Friday, March 5, 2010
IntroductionBased on the wishes by many people I was convinced to start a serial about modern application design. This serial will be completly based on my blog's source code, where I'll try to explain as many parts of my application as possible. As some parts were already covered in previous blog articles by me and other authors, I'll refer to them when the topics occur. In this first chapter I'm going to write about the basic setup of the application with some quirks which are rather not seen in most other setups.
Coding standard
This is probably the most important point, since it is leading through your entire application. There may still be people out there using some abitrary standard, if you can call it like that. But if there are more than only one person working on a project, you should definetly have one. For simplicity, I'm just using the Zend Framework coding standard.
Directory structure
As every project it always starts with choosing a specific directory structure. In my case I've choosen the Default modular directory structure proposed by Wil Sinclair, with some tiny modifications. One of those modifications is the additional library folder within my application folder, which holds the application library being non-specific to any module. I've also removed some folders of the proposal which I was not going to use. You may ask yourself, if a default directory structure is really important, and the answer is yes. When a developer comes from another Zend Framework project using the same structure, he will have no problem finding the way through your application within minutes.
Configuration
Many people nowadays use Zend_Tool to setup their initial project. As this automatically generates an INI config file, most developers stay with this kind of configuration. For many reasons I'm not doing that and instead using PHP config files, which I had written down about a year ago in another blog post.
Bootstrapping
Every new developer should be familiar with Zend_Application, which I and Matthew invented and published in Zend Framework 1.8. It has many benefits compared to the old and well-known procedural bootstrapping:
- Your bootstraping code is portable and reusable
- It is easier to test with PHPUnit
- You can use single resource for individual scripts
- It comes with many bootstrapping resources out-of-the-box
A few things to note about my quirks in bootstrapping: As I like to keep general services and models within the Default module, I am adding an additional resource autoloader for that module. I am also using module bootstrapping, as this automatically adds executes one bootstrap per module and registers a resource autoloader for it.
Routing
Many people just go with the default module route, which has some disadvantages. You have less control about the URIs and validation has always to be done in the controller. Also you will sooner or later get trouble with duplicate content, as many URIs can lead to the same controller-action. With custom routes, you can exacly define, how URLs should look like and do some rudimentary validation.
Exception handling
There are many kinds of exceptions, not the usual ones thrown by Zend Framework itself. For example, Zend Framework comes with three exceptions, which are "controller not found", "action not found" and, as of ZF 1.10, "route not found". Those can be used in the error controller to nicely display 404 (not found) pages. Additional to that, I'm using a custom App_PageNotFound exception, which is thrown by controllers if a request item could not be found. Another exception I use is the App_Permission exception. Those two will also be handled by the error controller to create appropriate output. All other exceptions will just generate a 500 (server error) page and log those exceptions.
To be continued …
In the next chapter of this serial I'm going to write about the service and model architecture used in my blog, stay tuned!
Comments to this article
Leave a comment
Please note that your email address will not be shown, it is only used to fetch your avatar image from gravatar.com and for notifications.


"...which I and Matthew invented"
You are so modest ;) :p
Nice initiative though, this series.
Thank Your! Nice article!
May you explain a bit more about exception handling and routing?
What exacly do you want to know more about the exception handling? Does probably the source of the error controller answer your questions?
http://site.svn.dasprids.de/trunk/application/modules/default/controllers/ErrorController.php
nice article... I hope on the next article about service and model architecture would be explained clearly :)
I also wish an article to explain the service and model architecture. Why did you put the code of the controllers in the services? Is the data model implementation you are using a kind of ORM approximation?
Excellent work Dasprid !! Keep on !!
Great art. It's good that someone is sharing how to develop quite advance application in ZF. Looking forward to reading next parts
Hi. I am curious if you use viewRenderer. I've recently read somewhere that if you care about speed in ZF you shouldn't use viewRenderer as speed was never a part of it's genetics. Also you should preload all of the classes in one php file (sort of a cache), not use Zend_App in production, etc. Any comments on this?
I know about the "benchmark" by Padraic. He had ripped down some things to get out more speed by sacrificing usability/simplicity of Zend Framework. You can surely abandon those features, but then you miss the advantages I pointed out for Zend_Application.
About the view renderer, it's esacly the same. in that case you have to call the render method (together with the layout-stuff) in every controller action. That may give you some more speed, but you end up with lots of duplicate code which is not fault tolerant.
The preloading of certain files/classes is surely a good point for production, as is the removal of require_once calls. But about the other points; In the end you are always faster with less OOP and more procedural code. So if you care that much about performance, a framework may not be the right choice.
thanks for sharing, this really catapulted my zend knowledge forward.
I really want to hear more about the models. I understand how you've implemented them, but it appears that your relationships (e.g. article->comments and article->tags) generate a lot of queries in the ArticleCollection. doesnt that kill performance? I was hoping for some lazy-loading or something more like hibernate...
Awesome code though, really like your style. The injection containers/services approach is genius.
Since those are one-to-many relation, they don't require more queries than any other approach.
I'm learning #zf.
The service layer and data mapper are so awesome!
Thank you very much!
Hi !
First of all, thank you very much for sharing all your work, it's really helpful, especially all the things related to services. I'm a C++ programmer and, although this language is really flexible and easy to use, it really gives me a lot of headaches in some points...
But well, I've read your source code, and I have some questions, I hope it's not too long :
1) I really really like your App_Model_Relation class. Really easy and elegant to do lazy-loading ! However, although it works really well in your examples because you have a one-to-many relationship (one article has many comments), it's not "as" elegant in a one-to-one relationship. For instance, in my app., user and user profiles are not in the same tables (hence, not in the same model). So, if I want to use this class, I have to do something like $user->profile->getIterator(). I don't like this approach because it directly exposes a function (getIterator()) that "should" (?) not be used outside the class. I can create a function getProfile in my user model, but well, it's not perfect.
Ok, this is just details, I agree ;).
2) To my opinion, the BIGGEST problem with your approach is that some part of the code are quite hard to maintain, due to a lot of duplicating codes.
For instance, imagine my profile class, that has some pre-defined fields. I want to add another field, so I have to : add a field in the form (that's normal), add the field in the model (that's normal too). But then, I have to insert also that field in the insert and update function of the services, as well as adding the field in the insert and update functions of the mappers. Quite a lot of code to maintaint just to "add" a field to my user profile.
Furthermore, it's really easy to make mistake in your approach because the convention names are usually not the same across the form (hence, HTML, where I use _ separated names), your database and your code (where I use camelCase). I find that first transforming my data (from post or get for instance) to an object in the service, and THEN transforming back my object to my data in the mapper is quite... a lot of code for nothing ! Of course it's logical, of course it's quite beautiful and, to some extents, easier to maintain if you want, for instance, get your data from another place than database (just change the mapper, and the service still works). But it's really pain in the ass to write !
I think one way to solve this problem would be to have consistent names across database, HTML and PHP, but well... quite a hack.
However, don't get me wrong, I really find your code really elegant and, to be honest, I'm rethinking all my app in order to take advantage of your code, but there are some things that I'm not happy with.
(By the way, Mr. Dasprid, can I contact you in order to ask some questions about the architecture of my project ? I'm doing my website using Zend Framework, but I'm really not satisfied by some points, and therefore I would love to have some advice from an exterior people, if you have some time ;)).
Thanks for your positive feedback, I'm glad that my source code and the blog helps other people in improving their own work. So let's see if I can answer all your questions:
1) That is a pretty delicious case. When I spot one-to-one relations, I either denormalize them if it makes sense, or I'd always (as in your example) get them in the datamapper of the user via a join. In my opinion, lazy loading does not make much sense for one-to-one relations, as a simple join won't take up much more performance. But taking the case you'd want to do that anway, I'd create another relation-class, which proxies all calls via PHP's magic __call(), __get(), __set() methods (and similars), which load the appropriate entity on request transparently.
2) This is in fact a small problem. You could surely try to use the same name in all places and automate a few more things, tho that would also reduce flexibility of the system. On the other hand, you can write scripts to handle adding/removing of fields, which lets you keep flexibility while still be able to easily add new fields.
If you like to contact me, go on. You'll find appropriate contact methods on this website :)
Hi, have you received my email ? =)
Yes I have, I didn't had time yet to answer it.
Hi, is the code of the site available for download ? because i tried to import it with svn but i need user/pass.
See you.
No, there is only the SVN repository, but it doesn't require username or password.
Ok, perhaps yesterday i was too tired and i made something wrong because today i could do a checkout without any problem. I like a lot the way you structure the code of the site and i think i could learn a lot from them.
One question, where can i set the APPLICATION_ENV to 'development', because is in production by default.
Thank you very much,
Keep with that good work !!
Me Again, now i read all the readme instructions and i see where to change the enviroment :-)
Thanks!
Only, thanxx, I'm learning a lot with you
I bumped into this article when I was looking for a good example to organize and structure the Models in my ZF applications. You approach gives me fresh new insights in developping with ZF.
But I was wondering why you don't make use of Zend_Db_Table, Zend_Db_Table_Row and Zend_Db_Table_Rowset? But I guess you'll cover that in your next post on the Models and Services.
cheers
about "Routing", i know how it can help to control the URL but have no idea how it can prevent "content duplicating" and "in controller validating" !?
Thanks for this article! It's great to read this because I'm on the way to create a new project with ZF at the moment so I can use these tips directly. ;)
By the way ... the idea of making your website's source code available to all of us was one reason for me to start working with ZF more and more.
Greetings
Marc
Hi,
Great article however I'm confused about one thing: because there is no index action in the DefaultIndexController how does it know what to display when you visit dasprids.de? I'm sure I'm missing something obvious but cannot figure it out.
Thanks,
Roger
When's the next article? I'm interested to know the thinking behind the service and model architecture :)