Wrong Way Go Back Traffic  SignageDefining a PHP method is quite standard : a function only requires a name and arguments. The arguments are its signature, just like this :

function x($arg1, $arg2, $arg3) {}

Arguments may, among other things, have default value. When this is the case, the arguments has to be at the end of the signature. Thus,

function goodSignature($arg1, $arg2 = 2, $arg3 = 3) {}

function badSignature($arg1, $arg2 = 2, $arg3) {}

At that point, you probably haven’t learnt anything new. This is all basic PHP knowledge. However, the trap is set.

The traps is set in motion when one realize that PHP do compile all the above mentioned code, good or bad syntax. This is right, ‘php -l code.php’ will say ‘No syntax errors detected in test.php’, even if the syntax doesn’t comply with the documentation. The PHP binary will accept this code and turn it into something that it can execute.

Indeed, the default value mechanism is only called when the arguments are not provided. As long as the methods are called with all or more of the arguments, the code do work flawlessly :

<?php
function x($a, $b = 3, $c) { print "$a $b $c\n"; }
x(1, 2, 3);
x(1, 3);
?>
1 2 3
1 3

On the other hand, if any argument is missing, PHP will assign the values in order, end up missing one argument, and then, check if there are any default value, do not find any for the third argument, and emit an error.

PHP Warning: Missing argument 3 for x(), called in /test.php on line 6 and defined in /test.php on line 3

Warning: Missing argument 3 for x(), called in /test.php on line 6 and defined in /test.php on line 3

PHP Notice: Undefined variable: c in /test.php on line 3

Notice: Undefined variable: c in /test.php on line 3

This will be exactly the same error if only one argument is provided : the method signature provide a default value for the second argument, and if this one is missing, then the value is used. Thus, calling the above function with only one argument still emits the same error :

PHP Warning: Missing argument 3 for x(), called in /test.php on line 6 and defined in /test.php on line 3

Warning: Missing argument 3 for x(), called in /test.php on line 6 and defined in /test.php on line 3

PHP Notice: Undefined variable: c in /test.php on line 3

Notice: Undefined variable: c in /test.php on line 3

How come anyone notice this ? To be true, all this happens as the application gets old. At some point, the method will need some upgrade, and the addition of a new argument. Then, to avoid checking all the function calls, a default value is provided. The application bearing some legacy code, the previous arguments can’t have any default value, so it are left this way. The best part, is that PHP will accept this new code without problem. It is even possible to run the application without any complain from the executer… Well, of course, that will be until someone use the old style signature.

Another funny situation that works (or not), is that the signature accepts multiple arguments with the same name : when running such code, the last argument’s value will be the good one.  This will not raise any error, not at compilation, nor at execution.

<?php
function x($a, $a , $a) { print "$a\n"; }
x(1, 2, 3);
?>
3

In the end, these are good reasons for code review. These syntax points are very easy to spot by reading the code. Sadly, they do appear in the code. I don’t think we need more checking on PHP side : this plate-form is a scripting plat-form, not a compiler, which will be slower but more thorough. PHP does some checking, although only at execution time. This is a very late stage  : remember, the later the bug is discovered, the more expensive it is to fix.