Overloading Constructors in PHP

Anyone who’s ever programmed in something like Java has probably written an overloaded constructor or two in their life. The ability to use different constructors for different circumstances is fundamental to both the polymorphism and code-reusability parts of OOP, and are amongst the fundamental tools of the trade.

PHP, having started out as a simple web-interaction language, and having only recently added real support for OOP programming, does not support constructor overloading. Annoyingly, Netbeans 6.5.1 doesn’t kick up any sort of warning if you attempt to overload a variable. The page simply would not render, without any mention of why. To make matters worse: it seems that this is such a fundamental issue in PHP that it doesn’t even get to a point where you can attach a debugger and see where things are breaking. You either know this, or you end up sitting in front of an empty browser window scratching your head.

So how can you “overload” constructors in PHP anyway? by using optional arguments, of course!

consider the following function declaration:

class PHPExample{
    public function __construct(array $inputArray="", $in="")

The function is obviously the (one and only) constructor method for its class. Yet any of the foolowing calls will invoke it correctly:

$A = new PHPExample();
$A = new PHPExample(array("A","B","C"));
$A = new PHPExample(,4);
$A = new PHPExample(array("A","B","C"), 4);

The key to this “psudo-overloading” is the list of arguments a function can take. In PHP, you can designate a default value for an argument. For example:

function add ($i, $j=1){
   $k= $i+$j;
   echo $k;

If you called the function add(1,2) you would get the response 3.
However, if you called add(1) the function will use it’s default value, and will respond with 2.

So what happens if the default value is null (ie “”)? Then the argument becomes optional. If the function call specifies the argument, it is used. If the call doesn’t have a value for the argument, the argument’s default value (null) is used, and the argument is thus ignored.

So now we have our “psudo-overloading”: Instead of writing different constructors for each set of arguments, we simply write the different senarios into the single constractor. For example:

public function __construct($in=""){
   if(is_array($in)) {

There just  are a couple of things to keep in mind when using optional variables:

First, optional arguments must come at the END of the argument list:

public function __construct(array $inputArray, $in="") Good

public function __construct(array $inputArray="", $in) Not Good

Second, you must account for optional arguments that you are not using, if you are using arguments that come later in the argument list:

$A = new PHPExample(,4); The comma tells PHP that the 4 is the second argument in the list.

This is by no means a perfect method, and one must hope that eventually PHP will come out with a version that does support constructor overloading. Until then, this is a workable, if possibly a little messy, workaround.


PHP variable fun

A little thing I learned the other day about PHP which may  be useful and is definitely fun:

In PHP a variable identifier can be a combination of any letter, number, and certain ASCII characters (that's actually not quite true, but that's irrelevent). The way PHP identifies a variable is by having a $ in front of it. $thisISaVariable is a PHP var, where as thisISaVariable is not. Remember that PHP is a weakly-typed language, so you don't need a type decleration. Any of these statements are valid:
$myvar=5;  //creates an int var
$myvar=6.7;  //creates a float var
$myvar = "Thisis";  //creates a string var.

Where this gets interesting is in the fact that PHP does it’s variable substitution on the fly. Consider this:

$myvar= "ThisIs";
echo $myvar ${$myvar}


In the first line PHP sets $myvar to “ThisIs”. It then gets tot he second line where it finds a $ sign. Everything after the sign is the variable name, which is stored in a different variable called myvar. PHP dereferences $myvar to find “ThisIS” so it sets $ThisIs=Fun. And thus we get the output above.

How is this useful? Because it allows you to input something into a variable without knowing the variable name at compile time. You’d notice that in the example above, although a variable with the name $ThisIs was created by the program, it’s name was never explicitly used. We could have easily had different input put into $myvar and created any number of differently named variables, without having to change the script one bit. Neat.