Questioning My Faith In Object Oriented PHP
I first came accross OO at Uni and I ‘got’ it straight away. After learning the basics of inheritance, abstract classes etc, I went straight to the GO4 book and have been an object/patterns junkie ever since. This was all in Java, and there was no other way to solve problems. It had to be OO.
Fast forward a few years and I’m building fairly basic websites for a living using PHP. You don’t need OO for these to work. A contact form would be the most complex thing we have going, so there’s no use busting out the command pattern just for that.
A few years later, and I’m moving on to full on CMS’s, accessing MySQL databases and interfacing with web services. At that stage, I naturally reacted by using patterns like command, data mapper, registry and loads others. They were the most natural tools available to me, PHP 5 was coming of age and life was good.
At the same time however, I felt like I was the only one. PHP Developers who had been at it for six or seven years longer than me just weren’t that into OO. I saw examples where objects were used here and there, or that perhaps used OO libraries like ZEND, but nothing hand-rolled that harnessed the sheer power of OO Design Patterns as they were intended.
This made me question my beliefs a little about OO. Is it really necessary? And if it is then why weren’t these seasoned PHP developers using it? Surely for every benefit that you can list about OO, couldn’t you simply respond with ‘you can do that with functions’? Let’s take a look at some of the commonly mentioned advantages of OO and see if we can answer that way.
Encapsulation/Modularity
The story goes that OO allows you to ‘encapsulate’ certain functionality in your program. All this means is that certain parts of code are responsible for a specific, well defined functionality. The details of how this code implements that functionality are hidden from the rest of the program, the benefit being that you can change that code without having to make knock-on changes in other parts of the program. Also, you could in theory swap out that functionality for a completely different bit of code as long as the expected input and output are the same. The thing is, with a bit of discipline, you can encapsulate parts of your code using functions, so OO isn’t really bringing anything new to the table there.
Code Reuse/Extensibility
In OO you can ‘re-use’ classes using inheritance. Say you built a class called ‘car’ with all sorts of car-related functionality like ‘accelerate’, ‘break’, ‘ignition’ etc. Let’s say you wanted to create another class called ‘convertible’. Writing ‘accelerate’, ‘break’, ‘ignition’ and all those other methods again for ‘convertible’ is a waste of time and introduces a lot of potential for error. Instead you make ‘convertible’ a subclass of ‘car’ and ‘convertible’ inherits all those behaviors. Again however, you can make perfectly re-usable code with a system of functions that go from general utility functions to specific client actions. Again ‘you can do it with functions’.
After doing a bit of googling, all other touted benefits of the OO state of mind strike me as quite subjective observations. Things that only make sense if you’re already using an OO system. The bottom line is that there’s absolutely nothing you can make a computer do with OO that you can’t make it do with simple procedural programing. There are no hard, logical reasons for going with OO over doing the same thing with a system of functions. The benefits only start to show themselves if we start questioning the foundations of why we use PHP or any other high level programming language in the first place.
Managing Complexity
All programming languages apart from machine code are there to manage complexity. That’s it. They act as an intermediary between the human programmers and the machine (and potentially, other machines). Some languages like C and assembler are closer to the machine, and others like ruby try to make things as easy (and even as fun) as possible for the programmer. The question then is not whether we can do things with OO that we can’t do with simple functions. The question is, which paradigm manages complexity better? Which acts as a better interface between the programmer and the machine?
After we get past a certain amount of complexity in a system, I’d argue that (for us mere mortals at least) using OO is the only sane way of managing that complexity. Using just functions and arrays to build a well designed, modular system would require a level of discipline that the average developer (including me) just doesn’t have.
The productivity benefits of using an OO system are well-advertised on the net. I still see them as subjective, but if you buy into the whole OO paradigm, this can translate to measurable productivity gains. Another benefit is that if another developer who knows OO picks up your code, he can quickly form a mental picture of how your application works based on the patterns you’ve used. Also, because of the ‘half-baked’ nature of patterns, it provides you with a vocabulary for prescribing general solutions to common, complicated problems that you come across when building applications.
OO Adoption Among PHP Developers
As to why more senior PHP developers haven’t adopted OO, the jury is still out. I think it’s a combination of factors:
- PHP has only had decent support for OO since PHP5. More senior developers, by definition would have worked with earlier versions where incorporating OO principles wasn’t a major focus.
- OO/Design Patterns are relatively hard for PHP coders*. The basic concepts are easy, but until you grok the general themes (composition over inheritance, coding to an interface etc) and the reasons therein, it can all seem like a big waste of time. Senior developers with a hard-won toolkit of techniques that work without OO may not have the patience to buckle down and learn all this.
- Lack of a strong ’software engineering’ culture. PHP developers typically go from designing websites in HTML/CSS to throwing together a few scripts in PHP and then finally building complex CMS-like web applications. At no point is there any reason for them to identify with ’software engineers’ in the traditional sense. However OO is more or less a foregone conclusion amongst Java, C++ and Ruby developers.
Because of the low adoption of OO in PHP circles, there are one or two parts of sites I built that I deliberately ‘dumb down’ so that the average developer can work with them. Specfically, I find that a front controller introduces way too much complexity for Joe the PHP coder. Even though I know there would be all sorts of flexibility advantages of using front controller, I stick with a simple page controller that fires off command objects to the rest of the system and gets back any and all required data. This sticks with the mental model of ‘one .php file per page’ and so is easy to work with even if you only have a basic knowledge of object syntax. On the one hand, the client gets the website, the managers are happy and the site is easily maintainable by junior developers. On the other, I’m essentially insulting the maintenance developers intelligence and delivering an inferior product.
OO is not intuitive when you first learn it. It’s especially difficult to learn when you can’t see the immediate benefits. But as far as I’m concerned, it’s the right way to do things for 99% of all non-trivial PHP based applications. While functions may encapsulate certain parts of your code, functions alone are not enough to manage the complexity of a large application. OO was thought up as a better way to manage the growing complexity of software, and it’s the defacto standard in non-PHP software engineering circles. It may not have a high adoption rate in the PHP wilderness, but I’m still going to push for it in every project I’m involved with.
* If I’m being honest, OO/Design Patterns are not that hard. Juggling pointers in C is hard. Concurrency is hard. Recursion/Functional Programming is hard. This is not a dig at PHP developers, it’s just that if PHP is all you do then you’re not likely to come accross particularly difficult problems. From that point of view, Design Patterns etc. are a relatively difficult concept to grasp.



