Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why php does not complain when referencing a non existing variable?

Tags:

php

reference

I was wondering why php does not complain when we reference a non existing variable (being it a plain variable or array), is this just the way it is, or there is something else I am missing? For example this code

<?php
$t = &$r["er"];
var_dump($r);
?>

throws no warning about a non existing variable.

Besides that the var_dump show this:

array(1) { ["er"]=> &NULL }

that &NULL is something I didn't really expected, I thought I would get a plain NULL.

Thanks in advance!

like image 223
Melsi Avatar asked Apr 06 '13 16:04

Melsi


2 Answers

If memory of the PHP interpreter reference var allocation serves me right, PHP will create a null element in the hash table with a key like the one you sent and reference it. This is visible by running the following test:

<?php
$i = 0;
$arr = [];
$arrS = null;
$v = memory_get_peak_usage();
for ($i = 0; $i < 150; $i++) {
    $arrS = &$arr[rand()];
}
$v = memory_get_peak_usage() - $v;
echo $v;

Until the default heap size, PHP will return exactly an extra 0 memory used - as it is still allocating already "prepared" array items (PHP keeps a few extra hash table elements empty but allocated for performance purposes). You can see this by setting it from 0 to 16 (which is the heap size!).

When you get over 16, PHP will have to allocate extra items, and will do so on i=17, i=18 etc..., creating null items in order to reference them.

P.S: contrary to what people said, this does NOT throw an error, warning or notice. Recalling an empty item without reference would - referencing an inexistent item does not. Big big BIG difference.

like image 70
Sébastien Renauld Avatar answered Nov 10 '22 03:11

Sébastien Renauld


throws no warning about a non existing variable.

This is how references work. $a = &$b; creates $b if it does not exist yet, "for future reference", if you will. It's the same as in parameters that are passed by reference. Maybe this looks familiar to you:

preg_match($pattern, $string, $matches);

Here the third parameter is a reference parameter, thus $matches does not have to exist at time of the method invocation, but it will be created.

that &NULL is something I didn't really expected, I thought I would get a plain NULL.

Why didn't you expect it? $r['er'] is a reference "to/from" $t. Note that references are not pointers, $r['er'] and $t are equal references to the same value, there is no direction from one to the other (hence the quotation marks in the last sentence).

like image 45
Fabian Schmengler Avatar answered Nov 10 '22 02:11

Fabian Schmengler