PHP vs. Python for Web Apps

These days, more and more people ask the Python vs. PHP question when they start out with a web application from scratch. I’ve developed PHP applications for 5 years but for the last couple of years I’ve been doing Python. This post is meant to note some of my observations. If you don’t want to read the whole of it, my opinion — opinion — is to stick with PHP for dishing out your *ML. Use Python in the back-end, if you must.

Production Worthiness

In terms of production stability and ubiquity, Python is still playing catch-up to PHP. PHP derives a huge benefit from its custom fit into the web development model, whereas Python is a general purpose language, with an adaptor for web development, called WSGI. PHP doesn’t do multi-threading, which is a great way to guide developers in a “shared nothing” line of thought. PHP and apache also work together to protect you from a lot of issues — you can enforce a limit on the memory your script uses for each request. Memory leaks are not a bother, thanks to periodic reaping of apache processes if you use the default prefork MPM and set MaxRequestsPerChild to a sane value (default is 4000).

Most Python web application frameworks would like you to build multi-threaded applications and recommend that you run your Python application as a daemon. From what I’ve seen so far, you really don’t want to be doing this. Multi-threading is not easy to begin with. Then there’s the GIL, which basically prevents a single Python daemon from utilising multiple CPUs and/or cores at the same time. That’s enough to be a show-stopper for an application being written in 2010. Third, I’ve seen random lock-ups, and slow memory leaks happen with Python daemons under the kind of production loads a small website may encounter (~ 1 Mbps network I/O; 20 reqs/sec).

The model that I would recommend is to run your Python application embedded in apache process space through mod_wsgi. This primarily ensures that you don’t need to renice up the priority of your Python daemon process to give it sufficient CPU time-share while under load and, more importantly, it enables the MaxRequestsPerChild clean-up mechanism.

Runtime Model

In terms of runtime model, one of the things to keep under consideration is that PHP would load all of its extensions, whether or not they’re used, while Python modules are loaded on demand. The PHP scenario is not too bad, though, since the memory usage is shared across all child processes, not multiplied across them. One of the differences that don’t stand out but are significant is that PHP’s extension library is almost all written in C, whereas Python libraries are not, to a very large extent. Many Python frameworks choose to implement a lot of important stuff like data structures in native Python. Given that a typical web application spends most of its time iterating through records from a database and doing various manipulations on it, having core functionality implemented in the script is not optimal. Python templates make the whole situation even worse.

That said, if you want to bet on the future, the JIT compilers being developed for Python might help you out. Then there’s HipHop for PHP.

Development Models

One of the big reasons for Python’s attractiveness as a development platform, apart from syntax and language features, is the presence of Ruby On Rails inspired frameworks. The most popular among them is Django, but I’ve also developed on Pylons and Werkzeug. I won’t list down the reasons why these frameworks are attractive, but they’re very good from a development model perspective.

PHP too has frameworks but they seem extremely loaded and superfluous to me. PHP itself is the framework for web development. It offers templating, it offers routing and it has a rich library of web development helpers. What it doesn’t do is a couple of things:

  • enforce MVC model out-of-the-box. You can write your entire application in one file and do it easily to start with
  • play well with the (IMO highly retarded) Java and GoF Patterns style of object oriented programming

One large application that I’ve worked on had thousands of files, each corresponding to a PHP class, with layers upon layers of wrapper classes without much individual responsibility. Some poor code organisation decisions also led to a scenario where each user facing page ended up including almost all of the 100k lines of PHP in the application.

Python would, to some extent, let you get away with this atrocity. More importantly, though, if you’re using the web frameworks, it could effectively prevent you from landing up in such a situation to begin with. If you know enough of MVC and shared-nothing fu, I think it’s worthwhile going with PHP as of now, if only for performance concerns.

How About PHP and Python?

Like I mentioned, one of the big reasons for using Python for web applications is the development model and the programming language capabilities itself. PHP takes care of the ‘V’ and ‘C’ parts of MVC but trying to write complicated models in PHP can lead you to pushing at the limits of the language’s development model.

One of the development models I am exploring (and have working in production already) is a two-tier application layer. The “model” lives as a separate tier of the application, accessed through JSON-HTTP services. The “front-end” is done entirely in PHP and is only responsible for generating web pages and handling browser-based interaction. This model has two benefits:

  1. The ‘front-end’ runtime is completely decoupled from the ‘back-end’, whether it be complexity, performance or scaling concerns
  2. You get usable webservice APIs right out of the box.

Someone’s quipped that not having APIs in 2009 is like not having a website in 1999. I wouldn’t disagree. Every web application that I’ve built since 2004 has eventually had to support some kind of APIs. That’s essentially the reason for wsloader‘s existence. It allows you to write your super heavy-duty back-end in Python, while requiring you to provide a portable interface, which it can automatically expose as a JSON-HTTP web-service. Writing 1000 words to make a plug seems preposterous, and probably is, so please don’t consider this as a plug!

  • Pankaj Jangid

    Symfony is comparable to django if not superior.

    • Tahir Hashmi

      That’s true, but it also doesn’t solve any of the problems that these frameworks create, with respect to separating the concerns of independent scaling for the back-end and front-end.

      Besides, PHP has a controller and template mechanism built-in. I don’t quite understand why you would put a routing library and a template library, both written in native PHP, on top. It’s will be nothing but slow-ow-slow.

  • Come on, dude, this post is full of unsubstantiated opinion!
    “Most Python web application frameworks would like you to build multi-threaded applications and recommend that you run your Python application as a daemon.” – where’s the reference for this?

    As you mentioned, using python under mod_wsgi allows one to program in the php style. So no real advantage to php there…

    Your second point, that much of the py frameworks are slower because they write intermediary data structures in pure python vs C – do you have any proof?? Also, you contradict yourself if you say one should use php because of speed on the front end, whereas one should use python on the backed because of – lack of speed??!!

    You may be right that php is a better choice – but there is no objective proof in this article that it is. Come on Tahir, we expect better from you!

  • Anonymous

    It turns out that only Werkzeug’s instructions default to daemon mode, while Django and Pylons instructions default to embedded mode. Sorry about that!

    Regarding Python frameworks being slower because they do a lot in native Python code, vs. PHP where extensions do a lot of heavy-lifting, yes, I have done scores of profiling runs on Python apps and I frequently find Python code to be a CPU hog. Ditto with PHP, with a lot of data manipulation happening in native PHP as opposed to extensions. The thing with PHP is that with PECL, you get C extensions to do a lot of stuff, so if PHP developers are conscious about leveraging the extensions, PHP stuff could end up performing better.

    Regarding Python on the back-end, I say, “use Python if you must, which is not the same as recommending Python for the back-end. Like I mention later on, people choose Python because it’s a nicer language to write complex code in, compared to PHP.

  • Kapparao

    Three things:
    1. I don’t like “$” in php.
    2. Your statement that “play well with the (IMO highly retarded) Java and GoF Patterns style of
    object oriented programming” may not be true. I read a book on design patterns in PHP. It
    has examples for lot of design patterns. Please check once.
    3. Python is slow and can u show design pattern examples in python?

    Iam me

  • GoF design patterns are language agnostic, as long as the language supports the OOP primitives that they require. So it’s possible to use them in PHP. The problem is that until PHP 5, and even through PHP 5, GoF style programming was not a good fit from performance perspective. Classic OOP performance has been getting better with newer versions of PHP.

    Even otherwise, I contend that GoF Design patterns are not the best way to program with feature-rich dynamic languages like PHP or Python. Design patterns are a sign of weakness in the programming languages. It’s still not a good practice to ignore language features that already provide similar facilities and construct GoF pattern scaffolding instead.

    See also Paul Graham’s views on design patterns and Peter Norvig’s presentation regarding design patterns in dynamic languages.

  • Abdullah

    You made my day. Thank you Tahir!

  • My

    HipHop for PHP transforms PHP source code into highly optimized C++. It was developed by Facebook and was released as open source in early 2010.

    HipHop transforms your PHP source code into highly optimized C++ and then compiles it with g++ to build binary files. You keep coding in simpler PHP, then HipHop executes your source code in a semantically equivalent manner and sacrifices some rarely used features – such as eval() – in exchange for improved performance.

    Facebook sees about a 50% reduction in CPU usage when serving equal amounts of Web traffic when compared to Apache and PHP. Facebook’s API tier can serve twice the traffic using 30% less CPU.

  • which one of these python framework or php framework is a better option for career?

    • Tahir Hashmi

      From a career point of view, it’s not good to restrict yourself to PHP or Python or whatever. If you do one project in PHP and another in Python, you’d gain much better experience than doing the same to projects only in PHP or only in Python.

      BTW, you might also want to take a look at Ruby on Rails.

  • From a career point of view, it’s not good to restrict yourself to PHP
    or Python or whatever. If you do one project in PHP and another in
    Python, you’d gain much better experience than doing the same to
    projects only in PHP or only in Python.

    BTW, you might also want to take a look at Ruby on Rails.

  • Pingback: Herbeth Santana()

  • hit9

    I stick to this rule: there is single way to do something.