Part of the EllisLab Network

Blog & News

For the Love of PHP

A couple months ago, a troubled user reported that his system was outputting the dreaded “Fatal error: Allowed memory size of ######## bytes exhausted” in his forum’s member area, even when viewing just a public profile.  Investigating, I found that on his system PHP was gobbling up an insane amount of memory when including our theme files.  Now, the theme files for the Member and Discussion Forum modules are basically a number of class methods that have HTML and ExpressionEngine variables stored in what is known as Heredoc strings.  Heredoc is a string format we often use to store HTML as it does not require that we escape single or double quotes in its content.  Any PHP developer will tell you that escaping quotes is one of the banes of their existence.

On a whim, I converted our theme files to simply hold the HTML in a single quoted string.  The memory used by PHP tanked on his system.  PHP was using over thirteen times (13x !!) more memory with theme files stored in Heredoc than with single quoted strings.  Rather curious.  We had never seen this kind of memory usage difference between string types, and the PHP bug tracker did not give a sure sign that this problem was known.  Fortunately, the fellow’s system admin bumped his memory usage up a couple MBs and the problem disappeared, and he thanked me for my time.  With the problem no longer needing a solution, I went back to work on various other things (like my tan).

Fast forward to last month as we started gearing up for 1.6.1 development. I still had this oddity in my mind and wanted to track it investigate a bit more.  As with all oddities in PHP, you typically want to create an independent test file, separate from any other factors (like the rest of ExpressionEngine’s code), to make sure nothing is interfering with your results.  Instead of using single quotes this time, I decided to use Output Buffering as it is far easier to convert to from Heredoc.  Here was the test file’s output on my local machine:

desc

Notice the PHP version at the top.  Amazed, Derek Jones uploaded the test file to his local machine, and this is what he got:

desc

Very different result on his (newer) version of PHP.  If anything, Heredoc was more memory efficient than Output Buffering and had an even faster load time.  We tried on a few other versions of PHP (5.2.3, 5.1.2, 4.3.9) and it was only PHP 5.2.2 that gave us this extreme over usage of memory for Heredoc.  I wish this was an exceptional case of PHP versions giving very different results when using a function or feature in the language.  It is not. 

Currently, with us supporting PHP 4.1 and above in ExpressionEngine, we are supporting nearly six years worth of PHP versions in our code.  And with MySQL, we are supporting MySQL 3.23.32 and above in our queries, which is closely approaching seven years of MySQL versions.  As you can imagine, with that many versions, there is a great deal of quirkiness that we are taking into account in our current code base and our future ExpressionEngine 1.x code base.

That, frankly, is madness on some level.  And so, with the release of ExpressionEngine 2.0, we will be raising our PHP and MySQL requirements for ExpressionEngine, as it is an intelligent decision to use newer, more feature-rich versions while no longer working around problems and limitations of older versions.  We have not finalized what those requirements are yet, so please do not ask in the forums because we will be unable to tell you.  I will say that, currently, we still intend to support versions of PHP prior to PHP 5, whose share of the PHP market is not even close to being high enough to completely abandon the PHP 4.x branch.

For users, when shopping for hosting or renewing your current accounts, take a few minutes to look into what versions of PHP and MySQL the host is using.  If they are not using PHP 5 in any capactity, ask when they do intend to switch.  It has been out for three years now, and it is very stable and supported by nearly all major PHP applications.  For MySQL, anyone not using MySQL 4.1 or above is not worth your time or money.

And for you PHP developers, good luck.  I mean, seriously, thirteen times as much memory?  Madness!