Search code examples
phpnullreferencereturn-by-reference

PHP and returning null references (revisited)


I've asked a question before, that essentially took the $null = null approach as a given, to returning a null reference in PHP.

After some cursory Googling, I didn't turn up much; leaving me to assume that the aforementioned approach is the best (read, only) way. However, it seems odd to me that PHP would (still) fail to support such functionality.

Anyways, if it's unclear; what (other, if any) ways exist to return null from a function by reference in PHP? I'm asking specifically about returning the null reference, not about the ternary operator issue that surfaced to explain my linked question.

For instance:

function &return_null(){
    return null;
}

$null_ref = return_null(); // fails

However:

function &return_null(){
    $null = null;
    return $null;
}

$null_ref = return_null(); // succeeds

I'm asking because I'm a bit OCD when creating reusable libraries; I really like clean code, with respect to however clean it can get in a given language. Using a placeholder $null = null makes my skin crawl, despite it achieving the desired functionality.


For the sake of completeness @yes123, here's the method snippet where this problem lives:

public static function &getByPath(Array &$array, $path, $delimiter){
    if(!is_array($path)){
        $path = explode($delimiter, $path);
    }
    $null = null;
    while(!empty($path)){
        $key = array_shift($path);
        if(!isset($array[$key])){
            return $null;
        }
        if(!empty($path) && !is_array($array[$key])){
            return $null;
        }
        $array = &$array[$key];
    }
    return $array;
}

There's also setByPath(), issetByPath(), and unsetByPath() in this ArrayPath class. I've aliased these static methods with the overloading magic. When an instance is constructed, an array is passed to the constructor (along with a delimiter), and the magic methods call the static ones using the referenced array of the instance. It's working pretty swell so far. In addition, I've written an alias function, array_path() that simply returns an instance. So for example, one can do:

$array = array(
    'foo' => array(
        'bar' => array(
            'hello' => 'world',
        ),
    ),
);

array_path($array, '/')->{'foo/bar/hello'} = 'universe';
var_dump($array);

/*
array(1) {
  ["foo"]=>
  array(1) {
    ["bar"]=>
    array(1) {
      ["hello"]=>
      string(8) "universe"
    }
  }
}
*/

Solution

  • I'm not sure if "references" and "clean code" go together... :(

    Anyway, references are not "pointers to" objects/values, rather, they are "pointers to" variables. Thus, only a variable is a suitable target. Said variable can "name" an object/value (read: be assigned a value), as demonstrated in the post. The post, however, does not return a "null reference" -- it returns a reference to a variable that "names" null.

    (And then people wonder why I reject the terminology that a variable "stores a reference to an object" when dealing with high-level languages/concepts...)

    Happy coding.