Electricmonk

Ferry Boender

Programmer, DevOpper, Open Source enthusiast.

Blog

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 */

The text of all posts on this blog, unless specificly mentioned otherwise, are licensed under this license.