PHP tips for optimizing

Google published a set of tips on how to increase the performance of PHP a while ago under the heading "Let's make the web faster". I recently came across the article again, and it's been changed a lot since last summer when it was published. At that time, a number of the tips were massively criticized - a lot of blog posts were written, comments made, etc. Seemingly, this has led to the article being changed, which is good, as some of the info on it previously was rather misleading. Most of what is left is alright, although one or two of those that have been allowed to stay are still dubious:

Don't copy variables for no reason

Sometimes PHP novices attempt to make their code "cleaner" by copying predefined variables to variables with shorter names before working with them. What this actually results in is doubled memory consumption (when the variable is altered), and therefore, slow scripts. In the following example, if a user had inserted 512KB worth of characters into a textarea field. This implementation would result in nearly 1MB of memory being used.

Although the above statement is correct (due to the 'when the variable is altered' which I'm presuming has been added later) the example that succeeds it does not in any way double the memory used. The example copies a variable and then echoes the copy - which doesn't amount to a change and hence won't actually create a copy of the variable. It would be nice to see the whole text revised instead of a bit of extra info inserted in a parenthesis ... oh well.

However, that's not the main point that struck me as odd. No, what got me paying attention is this bit:

Avoid writing naive setters and getters

When writing classes in PHP, you can save time and speed up your scripts by working with object properties directly, rather than writing naive setters and getters. In the following example, thedog class uses the setName() and getName() methods for accessing the name property.

Then follows an example with a class with public(!) properties and get/set methods. And of course the tip of not using getters and setters like that. However, is that really the tip that one should give programmers? What happened to encapsulation? Not to mention: who would ever write getter and setter functions for public properties?

In the theoretical world that people are being taught, you're told that keeping properties offlimits to the outside world is a good thing: it limits the knowledge the world can possibly have of your object and hence minimizes the chance for tight coupling due to someone figuring out that \$obj->property is possible and easier than \$obj->getProperty(). Why are people being told this? Because when later down the line you realise that you have to change obj::\$property to obj::\$some_other_property, you'll wish you never had the bright idea of making use of public properties. Specifically, going through code in many different places changing \$obj->property to \$obj->some_other_property really makes you annoyed ... there are much better ways to spend your time.

Of course, there's an alternative to fixing references to obj::\$property. It's called __get(), it's a magic method, and it's muchslower than setter/getter functions. In other words, using the hint from Google - which is supposed to speed up your apps - you're implicitly going down the road of tight coupling. Which means that:

Setting and calling the name property directly can run up to 100% faster, as well as cutting down on development time.

is a typical short-term view of things. Sure, development time is shorter if you don't have to write the ten extra lines of code for getters and setters, but development time is massively extended when you have to refactor your code to not use public properties any more. Not to mention that if you the mitigate that with __get() your code suddenly won't run up to 100% faster but more likely 100% slower (the code dealing with these properties, that is).

What should you do? You should design your objects properly, is what you should do. If some properties are core to the object and don't need a check when being set, then obviously you can go without getters and setters. However, if you're looking at an object that might change in the future or if you're dealing with properties that should be validated before being set (failing early is often better than failing late) or if you just want to minimize the signature of the object, then use setters and getters.