Home  >  Article  >  Backend Development  >  Detailed explanation of PHP citation - pitfalls and magical uses

Detailed explanation of PHP citation - pitfalls and magical uses

步履不停
步履不停Original
2019-06-21 15:18:132956browse

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.

0x00

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.

0x01

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.

0x02

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn