Friday, October 19, 2012

PHP Framework Comparison (update: opcode caching)

Reading about PHP frameworks, you'll get a lot about Symfony and Zend Framework. It is true that these frameworks have a lot of features and do great marketing. But what about performance and scalability?

There are 2 kinds of frameworks: those written in C as an extension and those written in PHP
Using a framework written in C will definitively give the best performance. But fixing (security) bugs and maintaining them requires C knowledge. If the documentation is not complete or incorrect, you might need to read the code to understand the functionality or wait for the maintainer to help you. So if you don't need super high performance, my recommendation is using a framework written in PHP.

Here is a test from Laruence (PHP core developer):

higher numbers are better, source

Here is another test from Zeev Suraski (Zend/PHP core developer):

higher numbers are better, source

Here is another excellent test from Wang Rui:

smaller numbers are better, source (with call graphs, response time, etc.)

Looking at the range of the numbers, you'll see that choosing the right framework can reduce the number of servers significantly. Also, response times can vary a lot between them. Using opcode caching for PHP (e.g. APC) is a key factor for good performance.

Are PHP frameworks dying?

PDO has shown that the best features from frameworks will make their way to the PHP core. I'm sure we'll see features like object relational mapping and expression based request routing some day in the PHP core. But PHP frameworks are growing much faster than the PHP core, so it is unlikely to see them disappearing.

Next generation frameworks

At the moment, there is no concurrency in PHP. Each script runs inside of one thread to generate the content. But most pages have several areas which could be generated simultaneously. A new extension called pthreads brings threads to PHP. So you can easily render several content areas in parallel, kill slow queries from your script, monitor the execution or do logging in a separate thread. This will bring up new frameworks which do all kinds of things in parallel to serve dynamic pages a lot faster.

Write your own framework?

Big players in IT business (Google, Facebook, Twitter, Yahoo) all write their own frameworks. If you have good ideas and implement exactly what your business needs, that's the way to go. Most full-stack frameworks are maintained by only 1 or 2 persons and are deeply integrated into consulting businesses, so writing your own is not more expensive or risky.
Using small (micro) frameworks with <10k lines is a good choice because you can adapt them quickly and maintenance costs are still low. If you want to get a new business started very quickly and sell it early, you should use an existing framework.

We must use a framework

The language PHP is already a great framework. Since most PHP frameworks only wrap existing functions into new methods, there is no direct need to use a framework ("reduce waste"). So you should look out where a framework reduces code size and complexity in your code. When extending or changing a framework, you need a strategy to migrate your changes to newer versions.

Using a framework from Facebook or Twitter will give me their success?

Yes, if you're exactly cloning Facebook and Twitter. No for all other cases. Think about problem and solution: choosing the solution before looking at the problem will not solve the problem and might produce new problems.

Typical problems in frameworks

  • code that is doing nothing but needs to be there to fit in a structure (example)
  • code that is only used if an extension is not loaded (e.g. json_decode())
  • too much abstraction (example)
  • too many lines of code (e.g. ZF1 260,000, ZF2 146,000 loc, Symfony2 173,000 loc, Doctrine2 70,000 loc), too hard to optimize, too hard to maintain
  • too many public methods (e.g. ZF1 13,000, ZF2 7,800, Symfony2 9,500, Doctrine2 4,400), too hard to learn
  • too many get/set methods (e.g. ZF2 4,080, Symfony2 3,800 (analysis from nikic))
  • too much documentation (e.g. ZF2 1000 pages and 500 examples)
  • too many includes (example)
  • unneeded wrapping (e.g. ZF2 echo StaticFilter::execute($str, "HtmlEntities", array("quotestyle"=>ENT_QUOTES)); echo (new Zend\Filter\HtmlEntities(array("quotestyle" => ENT_QUOTES)))->filter($str);)
  • code bloat (e.g. running a database query needs more than one line in the code)
  • migration from ZF1, Symfony1, Doctrine1

Build your own framework

Related articles:


performance (23) benchmark (6) MySQL (5) architecture (5) coding style (5) memory usage (5) HHVM (4) C++ (3) Java (3) Javascript (3) MVC (3) SQL (3) abstraction layer (3) framework (3) maintenance (3) Go (2) Golang (2) HTML5 (2) ORM (2) PDF (2) Slim (2) Symfony (2) Zend Framework (2) Zephir (2) firewall (2) log files (2) loops (2) quality (2) real-time (2) scrum (2) streaming (2) AOP (1) Apache (1) Arrays (1) C (1) DDoS (1) Deployment (1) DoS (1) Dropbox (1) HTML to PDF (1) HipHop (1) OCR (1) OOP (1) Objects (1) PDO (1) PHP extension (1) PhantomJS (1) SPL (1) SQLite (1) Server-Sent Events (1) Silex (1) Smarty (1) SplFixedArray (1) Unicode (1) V8 (1) analytics (1) annotations (1) apc (1) archiving (1) autoloading (1) awk (1) caching (1) code quality (1) column store (1) common mistakes (1) configuration (1) controller (1) decisions (1) design patterns (1) disk space (1) dynamic routing (1) file cache (1) garbage collector (1) good developer (1) html2pdf (1) internationalization (1) invoice (1) just-in-time compiler (1) kiss (1) knockd (1) legacy code (1) legacy systems (1) logtop (1) memcache (1) memcached (1) micro framework (1) ncat (1) node.js (1) openssh (1) pfff (1) php7 (1) phpng (1) procedure models (1) ramdisk (1) recursion (1) refactoring (1) references (1) regular expressions (1) search (1) security (1) sgrep (1) shm (1) sorting (1) spatch (1) ssh (1) strange behavior (1) swig (1) template engine (1) threads (1) translation (1) ubuntu (1) ufw (1) web server (1) whois (1)