Main Content

Improving your function calls (APIs) - General and PHP

Archive - Originally posted on "The Horse's Mouth" - 2010-04-24 22:37:55 - Graham Ellis

Some of the code at the Civil Service Department (CSD) where I worked on manpower planning models some 35 years ago would not have stood up to analysis against modern programming practice (but then ... that WAS 35 years ago). Indeed, some of the code "behind the curtains" didn't even stack up properly in those days. Perhaps we shouldn't have been surprised - for it was written by a very mixed crew of sandwich course students in the middle of their courses, and brilliant statisticians who were educated in an age before computers and had found their own coding techniques for writing functional code, but code that was impenetrable to students like myself who then had to maintain it.

The languages of the day were a bit short on facilities in some areas too, and that didn't really help; a prevalence of GO TO statements (and everything in capital letter) and a need to subscript check all arrays, without a list / vector / array list primitive for starters. Then, FORTRAN was a compiled language in an application area where, today, we would use scripting with (ideally, I think) Python.

So ... the CSD invited Colin Day to have a look at some code and one day he came in and talked us through some of the aspects that we should be looking at updating / amending to make the code more robust, more maintainable and more extendable as the project continued. That was a superb lecture; a real eye opener for me that marked a distinct change in direction for my coding, taking not only what Dr Day had to tell us to heart on the immediate project, but also looking at the principles behind his talk, and applying them thereafter and elsewhere.

I was reminded (yet again) of Colin Day's day with us yesterday - technical comment to follow - and wondered if I could find him via a search. One page says "We know 200 Colin Days in the UK" but then, amazingly, I think I have found the guy: [here]. It looks like a true case of "if you want a job doing, ask a busy man" for he had so much else happening when he came to the CSD - and I get the impression of someone who really has made a difference. He did to me - thank you, Colin.




The Heinz 57 varieties Subroutine

Subroutines / Functions / (procedures, methods, commands, macros, call them what you will!) are named blocks of code that help split code up. They're usually a good thing, allowing for modular testing and re-use of code - and in order to optimize those benefits, you want to keep the interface that others use to call your subroutines / functions small, simple, robust and unchanging.

Colin had found a subroutine in one of the CSD's manpower planning models that he called "the Heinz" - it had 57 parameters being passed in to it, and with parameters being in by position, a slight slip in coding would have been hard to locate and debug.

The shoe is on the other foot these days (though my feet don't fill Colin's shoes) and a delegate was asking me how - in PHP - I would reduce the complexity of calls to functions. And here are the tips / techniques that I offered, starting with the less effective ones and building to a climax!

• Optional parameters - put parameters which can usually be defaulted on the end, with the "most optional" on the very end - that way, you can often make the call shorter and simpler.

• Globals. There may be a small number of items that you pass in and out of lots of closely linked functions, and if that's the case, you may consider globals. Personally, I use them on web pages for my global error message block and flags, and PHP itself uses superglobals $_REQUEST, $_GET, $_FILE, $_SESSION, $_POST, $_SERVER, $_COOKIE and $_ENV.

• 2 way passing. If you add an & into the declaration of a variable in a function, that variable is passed by reference not by value. What that means is that you can alter the variable in the function, and the variable that's in the main code from which it originates is also changed. So this gives you an extra way of returning values - you get a "buy one, get one free" deal!

• Find the narrow waist. Your functions should logically group together code to perform a particular task, which should reduce the number of values to be passed in and out - you'll naturally find the narrow waistline of your application that lies between the broader chest and the thighs. And you can use the other techniques in this section to reduce further your parameters - like applying a corset to your code.

• Passing collections. Rather than pass a whole series of separate parameters, you can pass over collection variables. In PHP, that means you can replace (say) 10 parameters with an array of 10 elements - or (better) with an associative array with 10 elements or (best) with an object with 10 properties.


With these techniques applied together, you'll reduce your "Heinz 57" calls to calls which have just a handful of parameters - reducing, perhaps, 57 to a far more practical 5 parameters. I'm not going to give you a set rule as to what a maximum should be for good coding, save to save that I worry is I see a function where the number of parameters being passed in has reached double figures.

Note

PHP does not support "named parameters" where you can cherry pick and name parameters in the call. But you can achieve exactly the same results by passing in an associative array.


This article has been written to follow up on discussions on our Intermediate PHP for hobby / leisure users course which is running this Saturday and Sunday ... and will be running again later in the year. We also offer a beginners course for the leisure market, and more frequent weekday courses which are tailored for the business user. See [here] for an overview of all our PHP courses.