Explication détaillée de la citation PHP – pièges et utilisations magiques

步履不停
Libérer: 2023-04-06 22:02:01
original
3100 Les gens l'ont consulté

Explication détaillée de la citation PHP – pièges et utilisations magiques

J'ai récemment prêté attention au sujet des « citations PHP ». J'ai lu de nombreux articles approfondis et j'ai une compréhension plus approfondie des « citations » en PHP.

0x00

Regardez d'abord le code suivant :

$foo['hello'] = '0';
$bar = &$foo['hello']; // 引用!
$tipi = $foo;
$tipi['hello'] = '1';

print_r($foo);
Copier après la connexion

Q : Sortie 0 ou sortie 1 ? La réponse est 1.

Quel est le principe ?

Le noyau PHP utilise la structure zval pour stocker les variables. Dans le code PHP, nous utilisons la fonction xdebug_debug_zval pour le savoir.

Modifiez le code ci-dessus :

$foo['hello'] = '0';

xdebug_debug_zval('foo');
$bar = &$foo['hello']; // 引用!
xdebug_debug_zval('foo');

$tipi = $foo;
$tipi['hello'] = '1';

print_r($foo);
Copier après la connexion

Le résultat est le suivant :

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')
Copier après la connexion

$foo['hello'] passe d'une variable non-référence (is_ref=0) à une variable de référence (is_ref=1), et Le nombre de références est refcount=2.

Pourquoi ça ?

Selon PHP : What References Do - Manual explication :

$a =& $b; Cela signifie que $a et $b pointent vers la même variable.

$a et $b sont exactement les mêmes ici. Ce n'est pas que $a pointe vers $b ou vice versa, mais que $a et $b pointent vers le même endroit.

Combiné avec notre exemple, c'est-à-dire que lorsque $bar = &$foo['hello']; est exécuté, $bar et $foo['hello'] deviennent des "variables de référence", et elles "pointent vers le même endroit".

Ensuite, lorsque l'on copie ce tableau, on copie également la référence de son élément hello ; lorsque $tipi['hello'] = '1'; est exécuté, les "tipi['hello'], $foo['hello'] et $bar pointés sont modifiés. même endroit".

Ainsi, la valeur de $foo['hello'] devient naturellement 1.

0x01

PHPer qui a cité en profondeur aurait dû essayer cette syntaxe :

for ($list as &$value) {
    $value = 'foo';
}
Copier après la connexion

PHP ne recyclera pas les variables après la structure de contrôle, donc je ne l'expliquerai pas ici ; La fosse peut donc être agrandie à l'heure actuelle.

$foo['hello'] = '0';
$foo['world'] = 'A';
foreach($foo as &$value) { // 引用!
    // Do nothing.
}
$tipi = $foo;
$tipi['hello'] = '1';
$tipi['world'] = 'B';
print_r($foo);
Copier après la connexion

Le résultat ici est le suivant :

Array
(
    [hello] => 0
    [world] => B
)
Copier après la connexion

hello est normal, tandis que world est modifié en B ! La raison peut être explorée en combinant la fonction xdebug_debug_zval.

Donc, c'est une bonne habitude de simplement unset($value); y aller.

0x02

En fait, les citations ne sont pas que des écueils. Il y a encore de grands avantages.

Exemple :

$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],
];
Copier après la connexion

Comment convertir la table de séquence ci-dessus en arbre hiérarchique ?

Dans le passé, ou généralement, la première chose à laquelle nous pensions était le retour en arrière récursif.

Cependant, en utilisant la fonctionnalité de référence de PHP, la complexité temporelle peut être réduite à 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);
Copier après la connexion

Pour plus d'articles techniques liés à PHP, veuillez visiter la colonne Tutoriel PHP pour apprendre !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal