Detailed explanation of PHP citation - pitfalls and magical uses

步履不停
Release: 2023-04-06 22:02:01
Original
3092 people have browsed it

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);
Copy after login

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);
Copy after login

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')
Copy after login

$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';
}
Copy after login

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);
Copy after login

The output here is as follows:

Array
(
    [hello] => 0
    [world] => B
)
Copy after login

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],
];
Copy after login

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);
Copy after login

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!

Related labels:
source:php.cn
Statement of this Website
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template