Saturday, October 10, 2009

In my last post, Optimizing a php application in 5 minutes, a reader pointed out in a comment the performance problems that derive from using a framework. I believe generalizations of development techniques can be dangerous, so I'll present my thoughts on the advantages of incorporating a framework in a php application.

Here is Rob's original comment:

How would using a bloated framework help you scale in a big application? The Zend Framework is full of useless wrapper and abstraction classses (Zend_Session, Zend_Db spring to mind), which add extra overhead and require_once's to your codebase. If I were optimizing a large app, I'd use as much of PHP's native functionality as possible and look at implementing other CPU and resource intensive operations in C/C++. The Zend Lucene module for example, is implemented entirely in PHP and as a result scales horribly and performs terribly when compared with Lucene or clucene (for which there's a pecl extension).

The point is this, if you're looking at building performant apps that will scale, you shouldn't be implementing someone elses framework solution that has wrapper classes for native PHP functions and requires ten classes (require_once) just to bootstrap an application. PHP should look like PHP, and SQL should look like SQL. Don't use an ORM. You need to know what your SQL is doing. You need to be able to stick an EXPLAIN in front of a statement or move from in-line SQL to stored procedures. Avoid using expensive functions and classes written in PHP (Zend PDF, Zend Lucene). Look for pecl extensions or try and roll your own - they aren't that difficult once you get the hang of them. -- Rob Hofmeyr

I am a keen user of Zend Framework, one of the leading frameworks for the php language, and I want to show the reasons why I'm incorporating such a bloat in my applications.

1. Optimizing the right thing
As I pointed out in the post about profiling, you should take your time to optimize bottlenecks in an application, and finding them before intervening is mandatory. The Zend Framework Mvc stack has a fixed time cost per request, and while the application grows and the operations performed in the controllers multiply, remains more or less fixed.
The ports of the application, where it communicates with the external world, are more likely to need optimization and caching: web services and database calls are the most popular bottlenecks. Also intensive calculus operations can be moved in a C extension, but this is not the general case. The majority of php applications only deal with data, and bridge databases and other services with the end user. Note that my examples in the previous post were about a in-development application which is still fairly small at the moment: there were no references to external services. If your searches are heavy for the database, would you prefer to cut out the object-oriented library and construct sql by concatenation, or to cache results for some seconds?

2. Powerful library
Before rolling out your own solutions and reinvent the wheel, you should ask yourself some questions:

Am I likely to replicate all the functionality required by my application with the same quality of a collectively developed framework, with people that file bugs and submit good patches every day? With the same test coverage?

Am I likely to avoid the same bloat I am trying to avoid while adding more and more features to my own library?

Am I be able to develop all these things by myself, with time and cost restraints?

The cost of a popular solution derives from all the features that are included and that we do not take advantage of. But the maintenance burden is taken care by the core developers of the framework and by its community, while you're left with smoothing and optimizing the code to boost your performance (using a cache where it's needed, which it is often provided with the framework). Given the other advantages, it's a trade-off I'm willing to make.

3. Object model
Php frameworks provide a basic object-oriented library, even only by wrapping native php functions. This is necessary because I (and thousands of other php developers) deal with an object model. This means using an object-oriented approach and producing classes instead of functions. For the sake of unit testing and decoupled design, the infrastructure of an object model should be also object-oriented.
So why I'm using an Orm? Because it lets me work with my object model and then persisting all changes in a relational database. If not, I would have to write all my persistence and loading Sql by hand, and probably ending up in writing a general-purpose solution which I'll use for all my classes, to avoid maintaining boilerplate Sql all the time. This solution will resemble a generic Orm.
And why I'm using a framework? Because it has a general-purpose Orm included (although in php pure persistent-ignorant Orms are not stable yet; think of Doctrine 2 and Zend_Entity).

4. Standardization
Obviously a Zend Framework developer can work on many applications that rely on its components: his ability and knowledge is valuable on a wide range of codebases. In-house solutions are probably related to one or more projects and if you start to stretch them to cover more cases you'll find yourself building a generic framework like Zf.

5. Flexibility
A php framework fills the holes in the php language. Zend Framework takes advantage of the Spl and Pdo but it provides database adapters which really abstract away MySQL and Oracle, translation adapters which abstract away Gettext and Xml, feed objects that abstract away Atom and Rss... I can go on.
Object-oriented components make me happy: apart from Standard Php Library and PDO, much of the php functionality resides in functions while it will be more useful to me in classes and interfaces, giving me polymorphism and inheritance capabilities. This architecture is much more flexible than a procedural one.

For small and prototype applications a framework is not needed. But if you want to scale in lines of code, and not scaling in requests per second only, considering a framework can help you very much in the long run. Do not focus on saving cpu cycles, but developer's brain ones.

Frameworks are tools. Tools to get my job done (hopefully easier).No more and no less. So it's not that important if they are used in small or big, critical or non-critical projects but if they are used in the right place and when they can solve your problem or help you.

"Do not focus on saving cpu cycles, but developer's brain ones."

Do not focus on discussing frameworks but on good software design and the best possible way to develop your application.

Reading all those PHP blogs, you see far more discussions on when/how/why to use a framework.Sometimes it seems developers are spending more time on choosing, evaluating, testing, learning and discussing frameworks.

The first question often seems to be: "Which framework to use?"Instead of discussing how and why they should use good OOP and architectural design and spending time on refining that.And then asking: "That's what and how we wanna do it. Which tools may help?"

Using the wrong tool (i.e. framework or db) can hurt you - but making poor architecture decisions or not focussing on the design and the domain model can kill you.

Sudheer,I have read your article and you raise valid points for Zend Framework. If I'll have to advice ZF as a solution I'll direct people to your post.zampano,you're right in the sense that frameworks should provide only infrastructure code and the domain model should be independent of it: it's like insulating Java code from basic interfaces like Collection and List, designing more restrictive roles. But it's true that having a framework which encourages decoupling practices would be useful (unfortunately I can't think of any great example for php, given the early stage of development). Moreover, frameworks sometimes lock in your model code (using ActiveRecord pattern for example), so it's valuable to evaluate possibilities before choosing one.

1st you're always using a framework, be it specificaly made and optimized for a project or a 3rd party one. If every member in your team code in their own way and you have no framework to adhere to go kill yourself. Seriouly, do it now.

2nd from mine 5 year experience in web development, I know that ~70% of all app require an incremental/interactive approach and the best way to implement this is by focusing on simplicity and productivity. That's why most often, picking the most productive framework instead of the most performantic and gradualy optimize the bottlenecks later.

3rd those wrappers and generalizations serve several purposes, the most noble is they allow your code to be more succintand maintainable, so you can achive the optimization mentioned in point 2.

It's great to use a framework. I am using a lightweight framework called DooPHP with Zend Framework. I never like using Zend framework as my MVC base as it's too bloated and troublesome but I still like the large list of components.

It's probably the case that the platforms you have been programming on have a web-related version. For example if you are a Java programmer, you can start from servlets and web-MVC frameworks. The same goes for Python (Django), and many others.

We write lots of software but most of them really doesn't matter to the business, we are either doing a proof-of-concept, a model that isn't going to be managed or even a little assistant program that resolves such a filter use-case that it's not value making an investment lots of your time or power. In such cases Framework comes into existence and the reason why we are using it.