问题
I came across a code snippet which included $a = & $b;
but hadn't tested whether $b actually existed (if (isset($b))
). I wasn't sure how PHP handled this so I knocked up a quick bare test and now I'm even more intrigued.
$a = array('a'=>'b', 'x'=>'y');
$b = array();
$b[10] = &$a['a'];
$b[11] = &$a['ppp'];
var_dump($a);
var_dump($b);
echo (isset($a['ppp']) ? "SET" :" NOT SET") . "\n";
echo (isset($b[11]) ? "SET" :" NOT SET") . "\n";
It's bare code but what the output shows is:
Just the bare assignment of
$b[11] = &$a['ppp']
is enough,var_dump($a)
is reported as having 3 members not 2, even though no assignment was made for$a['ppp']
.$a['ppp']
is reported as having a value (NULL
) but alsoisset()=FALSE
.Meanwhile at the same time,
$b[11]
shows a valueNULL
andisset()=FALSE
even though its referent (apparently) does exist (!)
I appreciate that checking first fixes the 'problem', but I'm mainly looking for a deeper understanding. What's happening?
回答1:
Explanation is as simple as this
If you assign, pass, or return an undefined variable by reference, it will get created.
(emphasis mine)
That's what you're doing; Assigning an undefined index by reference so it gets created.
Example #1 Using references with undefined variables
<?php
function foo(&$var) { }
foo($a); // $a is "created" and assigned to null
$b = array();
foo($b['b']);
var_dump(array_key_exists('b', $b)); // bool(true)
$c = new StdClass;
foo($c->d);
var_dump(property_exists($c, 'd')); // bool(true)
?>
Example from PHP Manual
Then you have another question:
Meanwhile at the same time, $b[11] shows a value NULL and isset()=FALSE even though its referent (apparently) does exist (!)
That is also explained clearly on the manual
isset — Determine if a variable is set and is not NULL
isset() will return FALSE if testing a variable that has been set to NULL
Since it is NULL
, isset()
returns FALSE.
回答2:
The slot has to exist for you to be able to alias another variable to it (which is really what's going on here, PHP's "references" aren't really actual things as much as each "by reference" operation is a regular operation with copying replaced by aliasing), but it doesn't have to contain a non-null value, and doesn't until you assign it one (through either of its names).
来源:https://stackoverflow.com/questions/36215159/php-assign-by-reference-oddity