Home > Article > Backend Development > Detailed explanation of PHP citation - pitfalls and magical uses
Recently, I have been paying attention to the topic of "PHP Reference". I have read many in-depth articles and have a deeper understanding of "Reference" in PHP.
First look at the following code:
$foo['hello'] = '0'; $bar = &$foo['hello']; // 引用! $tipi = $foo; $tipi['hello'] = '1'; print_r($foo);
Q: Output 0 or output 1? The answer is 1.
What’s the principle?
The PHP kernel uses the zval
structure to store variables. In the PHP code, we use the xdebug_debug_zval
function to find out.
Modify the above code:
$foo['hello'] = '0'; xdebug_debug_zval('foo'); $bar = &$foo['hello']; // 引用! xdebug_debug_zval('foo'); $tipi = $foo; $tipi['hello'] = '1'; print_r($foo);
The output is as follows:
foo: (refcount=1, is_ref=0)=array ('hello' => (refcount=1, is_ref=0)='0') foo: (refcount=1, is_ref=0)=array ('hello' => (refcount=2, is_ref=1)='0')
$foo['hello']
From the non-reference variable (is_ref= 0
) becomes a reference variable (is_ref=1
), and the reference count is refcount=2
.
Why is this?
According to PHP: What does a quote do - Manual's explanation:
$a =& $b;
This means $a and $b point to the same variable.$a and $b are exactly the same here. It’s not that $a points to $b or vice versa, but that $a and $b point to the same place.
Combined with our example, that is, when $bar = &$foo['hello'];
is executed, $bar
and $foo['hello']
have all become "reference variables", and they "point to the same place".
Then when we copy this array, we also copy the reference of its hello
element; when $tipi['hello'] = '1';
is executed , the "same place" pointed to by tipi['hello']
, $foo['hello']
and $bar
is modified.
So, the value of $foo['hello']
naturally becomes 1
.
PHPers who have a little in-depth reference should have tried this syntax:
for ($list as &$value) { $value = 'foo'; }
PHP will not recycle variables after the control structure, so I won’t explain it here; So the pit just now can actually be extended.
$foo['hello'] = '0'; $foo['world'] = 'A'; foreach($foo as &$value) { // 引用! // Do nothing. } $tipi = $foo; $tipi['hello'] = '1'; $tipi['world'] = 'B'; print_r($foo);
The output here is as follows:
Array ( [hello] => 0 [world] => B )
hello
is normal, while world
is modified to B
! The reason can be explored by yourself with the xdebug_debug_zval
function.
So, casually unset($value);
is a good habit.
In fact, citations are not all pitfalls. There are still great benefits.
Example:
$catList = [ '1' => ['id' => 1, 'name' => '颜色', 'parent_id' => 0], '2' => ['id' => 2, 'name' => '规格', 'parent_id' => 0], '3' => ['id' => 3, 'name' => '白色', 'parent_id' => 1], '4' => ['id' => 4, 'name' => '黑色', 'parent_id' => 1], '5' => ['id' => 5, 'name' => '大', 'parent_id' => 2], '6' => ['id' => 6, 'name' => '小', 'parent_id' => 2], '7' => ['id' => 7, 'name' => '黄色', 'parent_id' => 1], ];
How to convert the above sequence table into a hierarchical tree?
In the past, or usually the first thing we thought of was recursive backtracking.
However, using the reference feature of PHP, the time complexity can be reduced to O(n)
.
$treeData = []; foreach ($catList as $item) { if (isset($catList[$item['parent_id']]) && !empty($catList[$item['parent_id']])) { // 子分类 $catList[$item['parent_id']]['children'][] = &$catList[$item['id']]; } else { // 一级分类 $treeData[] = &$catList[$item['id']]; } } var_export($treeData);
For more PHP related technical articles, please visit the PHP Tutorial column to learn!
The above is the detailed content of Detailed explanation of PHP citation - pitfalls and magical uses. For more information, please follow other related articles on the PHP Chinese website!