Samstag, 5. Oktober 2013

Optional Parameters in PHP, and NULL

Consider the following PHP5 code:

<?php
class A{
      function foo() {}
}
function f(A $a = NULL) { var_dump($a); }
function g(A $a) { var_dump($a); }
f(new A());
f(NULL);
g(new A());
g(NULL);


Now, consider its output:

class A#1 (0) {
}
NULL
class A#1 (0) {
}

Catchable fatal error: Argument 1 passed to g() must be an instance of A, null given, called in a.php on line 13 and defined in a.php on line 8

Okay. So, a parameter, with or without a type hint, whether required or optional, receives an A if given an A. No surprise there.

An optional, type-hinted parameter, when given a NULL, results in a NULL. I guess that's fine, too.

However, a required parameter can not ever be set to NULL.

You're right: Setting something to NULL in the parameter list means something totally different than setting something to NULL anywhere else in your code.

I guess what they were trying to do was force the = NULL, passing NULL "idiom" to represent the fact that the parameter is optional, and is not set. I guess the reason is that you can not default a type-hinted parameter to anything besides NULL. The function body can not distinguish between a NULL stemming from the default in the parameter list, and an actual NULL, and NULL is the only indication that the optional parameter was left out, so passing a NULL is disallowed in the case of a required parameter.

Or something like that. (If you omit the type hint, passing the NULL works perfectly fine, by the way, thus making it even more confusing...)

Regardless of how long, or how hard I think about it, it keeps making no sense at all. It is neither consistent, nor is it useful. It is, at best, an attempt of the language to be clever - an attempt, I should say, that went terribly terribly wrong. At worst, it is a result of some obscurity in the parser that nobody ever really thought through.

In any case, it makes me even more sad to be forced every working day to work with tools as broken as that.