Wednesday, June 13. 2012
Although it won't affect 99% of you or more, much of the code behind the scenes on pages other than my blog (which is run by a free system rather than something I wrote), is gradually being converted to OOP forms of PHP.
Sometimes this is relatively easy. Other times it's a pretty major undertaking.
So why? Well, I've also be learning to code for iOS devices and the Mac. This is all done in Objective-C (plus a visual editor for the UI that's drag and drop style goodness), which being built on a C-framework is pure OOP. The core framework protects you from some of the real quirks of C while giving you some of its own. But... and here's the rub... OOP approaches require dividing and chunking the code somewhat differently to writing procedural code (the more traditional, non-OOP form). Although I'm fairly comfortable writing Objective-C now, I'm truly most comfortable writing PHP and LSL. So writing PHP into OOP to do familiar tasks I find I can make sure I'm getting the alternative chunking sorted out and clear in my mind.
One really obvious difference is good practise for PHP-OOP generates a lot more files (one per class, plus one to handle the interface) as well as thinking about the problem differently.
To give an example, say you're doing a display of photos in an album sort of format so it makes sense to put them into a table. In procedural code you'd get an array of your picture links, loop through them slapping an img tag into each td tag to fill the table or similar. A bit of snazzy footwork to break for new rows, and you're done.
This gives you one file with a mess of loops in it and so on in a procedural approach. It's actually quite easy to understand though - you start the table, you get your data, you loop through your data starting with a row and a new row every few images, then a new cell per picture until it's done.
In OOP there are three obvious possible objects here. The table that you'd actually create pretty much the same way could be an object. Each row in it could be too/instead - you pass this object an array of picture names and it returns a chunk of code for each line. Finally, each picture or perhaps each bit of cell code could be it's own object that you then roll up into rows and tables. You could do any one, two or all three of these pretty easily. There probably isn't actually a "wrong" answer, although some are less good than others depending on the situation (if you regularly need more about one image you probably need an object per image for example, but if all you're going to do is store a list of img tags, a higher level structure - probably at the table level - makes more sense).
Having decided that, it's pretty easy to suggest ideas such as a generalised image-display table. Pass the object parameters for the number of images per row, size (height and width) of the image to display and so on. There could be other options too, like do you make links or similar but as you will see below I didn't do this in the end. It makes the first time you write the table object code harder to manage but if you do it this way then you get a reusable chunk of code for the next time you need to do a table like this.
In practice I went with three objects (and so three extra files). It worked out to be nicer to create two quite similar objects to handle extracting the data and creating an array of the cell code for each cell. Different objects because I need to handle somewhat different queries to the database and I decided to have the queries hard coded into the object rather than passed as a parameter. This is somewhat bad in terms of the pure abstraction of the objects but makes debugging the code much easier, but because it also depends critically on the structure of the table, copying and then editing the query in situ is hardly a problem compared to the benefit of easier debugging. Then there is a shared object that takes these arrays as an input, along with parameters for number of cells per row, height and width of the images and produces a nice table for you. This table code is basically infinitely reusable. The cell code will need editing each time to run the query and generate the right cell code each time, but that's OK.
I also created two login classes. One is very generic and handles the routine stuff - logging in, having password reminders sent, changing your password, registering as a new user etc. This is very reusable in almost all circumstances. In addition an extension class that uses all of that but adds some very specific functionality is there for those specific little things - in this case some people have to be able to peek into other people's pictures for example, so I needed a bit extra to handle that.
And therein lies the attraction of OOP. Here's a login class, there's a table writing class for images and a related cell generating class. Next time I need a login class, I create the user table as required, drop in the class and off we go.
Of course working in PHP gives you some fun and games that won't occur in iOS device coding. You can mix all of this with some AJAX-fu (and an extra file or two). One of my projects, in fact the first I approached with the intention of writing it all in OOP, the file to which you point your browser is basically HTML header and body code, including 3 divs. It's a PHP file because it has to work out the date and pass that through the AJAX. This extra layer of work adds yet more files of course, but if you have a page where a lot of things are updated/changed regularly in parts without changing the whole page it makes for a nicer user experience.
Display comments as (Linear | Threaded)
The author does not allow comments to this entry
Syndicate This Blog
Last entry: 2013-05-21 09:12
725 entries written
238 comments have been made