PHP Function Overloading
Tuesday, May 3rd, 2005
The other day I was looking if it was possible with PHP5 to do function overloading. For those that don’t know, function overloading is the technique of being able to call a single function in different ways.
Suppose, for instance, that you’ve got a function formatDate($date)
that returns a date formatted as a string dd-mm-yyyy
. The date could be specified using a string ‘yyyymmddd’ or an integer representing a unix timestamp (number of seconds sinds the epoch, which is January 1 1970, if I recall correctly). Function overloading then allows you to define two different functions with the same name, that can be called both with a String argument or an Integer argument. The functions would be defined as (pseudo-code)
String formatDate(String) {;} String formatDate(Integer) {;}
Unfortunatelly, PHP5’s Object Oriented capabilities do not seem to support this, which is a shame. I assume the reason for this is the fact that PHP is typeless, which means a string is no different from an integer. So when we define the formatDate function in PHP, it would always be the same thing:
function formatDate($string); /* Same as next declaration */ function formatDate($integer); /* Same as previous declaration */
But, there is a way around this, even though it’s a quite ugly one. Check out the following code:
class Atom { /* Ways this function can be called: * * new Atom( int $id) * new Atom(string $name) * new Atom( int $id, string $name, string $contents, array $categories) */ function Atom() { $argc = func_num_args(); $argv = func_get_args(); if ($argc == 1) { if (is_int($argv[0])) { /* new Atom(int $id); */ $this->id = $argv[0]; } else if (is_string($argv[0])) { /* new Atom(string $name); */ $this->name = $argv[0]; } } if ($argc > 1) { $this->id = $argv[0]; $this->name = $argv[1]; } if ($argc > 2) { $this->contents = $argv[2]; } if ($argc > 3) { $this->categories = $argv[3]; } } }
Care must be taken to make sure that the base type of a parameter you pass to the function is the correct type. This is because types can be something else than they appear to be. For instance,
$integer = "10";
is actually a string, while
$integer = 10;
is a real integer.
This poses problems when receiving input from the client-side, because there is no way to accurately determine the type of the variable. Thankfully, it’s possible to do type casting in PHP:
$integer = "10"; $a = new Atom( $integer ); /* Calls like Atom( string ) */ $b = new Atom( (int) $integer); /* Calls like Atom( int ) */
Granted. The resulting code is a lot less readable then usual, but it is a possible way for doing function overloading. I tend to only use this in object constructors, because litering my other functions with all this overhead is not something I like to do.
For other functions, I rather use:
function getThingyById($id) { }; /* Integer */ function getThingyByName($name) { }; /* String */