Re-comprendre les références PHP

不言
Libérer: 2023-03-23 20:34:01
original
1097 Les gens l'ont consulté

Cet article présente principalement la re-compréhension des références PHP, qui ont une certaine valeur de référence. Maintenant, je le partage avec tout le monde. Les amis dans le besoin peuvent s'y référer

Cause :

Pendant. développement quotidien, nous rencontrerons le besoin de construire un arbre, de construire une structure arborescente grâce à la relation entre id et pid, puis de parcourir l'arbre et d'autres opérations. Il existe deux manières de l'implémenter : 1. Récursion, 2. Référence
Les avantages et les inconvénients de ces deux méthodes sont également évidents.

  1. La récursion est plus facile à mettre en œuvre, mais à mesure que la quantité de données de comptage augmente, ses performances sont très faibles.

  2. Le concept de citation lui-même est facile à comprendre, et ses performances sont également très bonnes, mais il existe encore certains seuils pour bien l'utiliser, et ce n'est pas facile à écrire.

La raison pour laquelle j'ai écrit cet article est que je suis tombé sur une très bonne solution ces jours-ci, ce qui m'a fait à nouveau comprendre la citation. A travers cet article, résumez vos résultats d'apprentissage. Ok, puis passez directement au code.

Pratiquez

Si vous pouvez comprendre le code suivant après l'avoir lu, cela signifie que vous maîtrisez vraiment la citation, et vous pouvez également ignorer cet article directement ~.
function buildTreeByReference($data, $id = 'id', $pid = 'pid', $child = "children")
    {
        $tmp = []; //以id为健,$value为值的容器,可以很巧妙的判断根节点元素
        $tree = [];  
        //利用引用,对$data的数据进行操作
        foreach ($data as $key => &$value) {
                // 
                $tmp[$value['id']] = &$value;
                
                if (!isset($tmp[$value['pid']])) {
                    $tree[] = &$tmp[$value['id']];
                }else {
                     $temp = &$tmp[$value['pid']];
                     $temp[$child][] = &$value;
                }
                unset($temp, $value);
        }
        return $tree;
    }
Copier après la connexion

ok, ne parlons pas d'autres choses d'abord, vous pouvez tester cette méthode avec les données suivantes

$data= [
            ["id" => 1, "pid" => 0 , "name" => 'Universe'],
            ["id" => 2, "pid" => 1 , "name" => 'Earth'],
            ["id" => 3, "pid" => 2 , "name" => 'China'],
            ["id" => 4, "pid" => 3 , "name" => 'Beijing'],
];
Copier après la connexion
Plus : Cette méthode doit faire attention. , il nécessite un parent Le nœud est le premier, ce qui ne convient pas aux données non ordonnées, donc s'il n'est pas ordonné, il doit être trié en premier

S'il n'y a pas d'accident, le résultat imprimé doit l'être. comme suit :

array(1) {
  [0]=>
  array(4) {
    ["id"]=>
    int(1)
    ["pid"]=>
    int(0)
    ["name"]=>
    string(8) "Universe"
    ["children"]=>
    array(1) {
      [0]=>
      array(4) {
        ["id"]=>
        int(2)
        ["pid"]=>
        int(1)
        ["name"]=>
        string(5) "Earth"
        ["children"]=>
        array(1) {
          [0]=>
          array(4) {
            ["id"]=>
            int(3)
            ["pid"]=>
            int(2)
            ["name"]=>
            string(5) "China"
            ["children"]=>
            array(1) {
              [0]=>
              array(3) {
                ["id"]=>
                int(4)
                ["pid"]=>
                int(3)
                ["name"]=>
                string(7) "Beijing"
              }
            }
          }
        }
      }
    }
  }
}
Copier après la connexion

Si vous ne la comprenez toujours pas, ce n'est pas grave Analysons-la une par une
En fait, pour bien comprendre cette solution, vous devez la comprendre. deux parties.

  1. Principe d'affectation foreach

  2. Principe de citation

foreach
    $data = ["student", "teacher"];
    foreach ($data as $index => $item) {
    }
Copier après la connexion

Notez qu'à chaque passage dans la boucle, les "valeurs" de $data[0] et $data[1] sont copiées puis affectées à $item

Citation (Assurez-vous de l'essayer vous-même)
$a = 1;
$b = &$a;
$c = $b;
$c = 2;
猜猜看 $b = ?;
Copier après la connexion

Si vous avez des questions sur la citation, cliquez sur moi

ici, si vous pouvez comprendre le foreach et la citation ci-dessus, et je peux comprendre tous les processus d'exécution de cette solution, alors félicitations, vous avez très bien appris. Mais si vous rencontrez encore des difficultés, ce n'est pas grave, procédons étape par étape

<. 🎜>Analyse

ok, respire profondément et suis mes pensées, allons-y étape par étape.

  1. Jetons d'abord un coup d'œil à la fonction d'origine

function buildTreeByReference($data, $id = &#39;id&#39;, $pid = &#39;pid&#39;, $child = "children")
    {
        $tmp = []; #以id为健,$value为值的容器,可以很巧妙的判断根节点元素
        $tree = [];  
        #利用引用,对$data的数据进行操作
        foreach ($data as $key => &$value) {
                
                #&$value取到$data元素对应值的引用
                
                $tmp[$value[&#39;id&#39;]] = &$value;
                
                #以$value[&#39;id&#39;]为键,&$value引用为值push到$tmp中,
                #这样可以巧妙的判断当前元素是否为根节点
                
                if (!isset($tmp[$value[&#39;pid&#39;]])) {
                    #将根节点push到$tree中
                    $tree[] = &$tmp[$value[&#39;id&#39;]];
                    
                }else {
                     #若当前元素的父节点存在于$tmp中, 引用获取$tmp中对应父节点的值
                     $temp = &$tmp[$value[&#39;pid&#39;]];
                     #然后将当前元素push到其父节点的children中
                     $temp[$child][] = &$value;
                }
                #为了不引起变量污染, 引用用完后,需要unset掉
                unset($temp, $value);
        }
        return $tree;
    }
Copier après la connexion
  1. Première boucle

function buildTreeByReference($data, $id = &#39;id&#39;, $pid = &#39;pid&#39;, $child = "children")
    {
       # $tmp = [];
       # $tree = [];  
        
       # foreach ($data as $key => &$value) {
                // 
                $tmp[$value[&#39;id&#39;]] = &$value;
                
                if (!isset($tmp[$value[&#39;pid&#39;]])) {
                    $tree[] = &$tmp[$value[&#39;id&#39;]];
                }else {
        #             $temp = &$tmp[$value[&#39;pid&#39;]];
        #             $temp[$child][] = &$value;
        #        }
                unset($temp, $value);
        }
        return $tree;
    }
Copier après la connexion
Situation variable :

$data[ 0] = ["id" = > 1, "pid" => 0 , "name" => 'Univers'];
$tmp[1] = &$data[0];
$tree[] = &$data [0]

  1. Deuxième boucle

function buildTreeByReference($data, $id = &#39;id&#39;, $pid = &#39;pid&#39;, $child = "children")
    {
       # $tmp = [];
       # $tree = [];  
        
       # foreach ($data as $key => &$value) {
                // 
                $tmp[$value[&#39;id&#39;]] = &$value;
                
        #        if (!isset($tmp[$value[&#39;pid&#39;]])) {
        #            $tree[] = &$tmp[$value[&#39;id&#39;]];
                }else {
                     $temp = &$tmp[$value[&#39;pid&#39;]];
                     $temp[$child][] = &$value;
                }
                unset($temp, $value);
        }
        return $tree;
    }
Copier après la connexion
Copier après la connexion
Copier après la connexion

Situation variable :$data[1 ] = ["id" => 2, "pid" => 1 , "name" => 'Terre'];
$value=&$data[1];
$tmp[2 ] = &$data[1];

Remarque : $temp est &$tmp[1], qui pointe vers la même adresse que $data[0 ]
donc $temp ['children'][] = &$value , le résultat de l'opération est :

$data[
    [  
     "id" => 1,
     "pid" => 0 ,
     "name" => &#39;Universe&#39;
     "children"=>[
                 &$data[1],   //注意:存储的是引用
         ]
     ]   
     ...
]
Copier après la connexion
Copier après la connexion
4. 🎜>Statut de la variable :

$data[2] = ["id" => 3, "pid" => 2, "name" => = &$data[2];
function buildTreeByReference($data, $id = &#39;id&#39;, $pid = &#39;pid&#39;, $child = "children")
    {
       # $tmp = [];
       # $tree = [];  
        
       # foreach ($data as $key => &$value) {
                // 
                $tmp[$value[&#39;id&#39;]] = &$value;
                
        #        if (!isset($tmp[$value[&#39;pid&#39;]])) {
        #            $tree[] = &$tmp[$value[&#39;id&#39;]];
                }else {
                     $temp = &$tmp[$value[&#39;pid&#39;]];
                     $temp[$child][] = &$value;
                }
                unset($temp, $value);
        }
        return $tree;
    }
Copier après la connexion
Copier après la connexion
Copier après la connexion
$tmp[3] = &$data[2];

Remarque :
$temp est &$tmp[2], ce qui pointe identique à $data[1] Address

Donc $temp['children'][] = &$value, le résultat de l'opération est :
Notez ici :Ceci est le valeur stockée dans les enfants lors de la deuxième boucle La référence de $data[1]

pendant le troisième cycle est $data[1]['children'][] = &$value, et $value pointe vers $ data[2]

, donc le résultat est :

5 La quatrième boucle
$data[
    [  
     "id" => 1,
     "pid" => 0 ,
     "name" => &#39;Universe&#39;
     "children"=>[
                 &$data[1],   //注意:存储的是引用
         ]
     ]   
     ...
]
Copier après la connexion
Copier après la connexion


Situation variable :
   $data[
        [  
         "id" => 1,
         "pid" => 0 ,
         "name" => &#39;Universe&#39;
         "children"=>[
                       // &$data[1],   //注意:存储的是引用
                         [
                           "id" => 2, 
                           "pid" => 1 ,
                           "name" => &#39;Earth&#39;
                           "children" => [
                                   &data[2] //注意:存储的是引用   
                            ]
                         
                         ] 
                         
                     ]
             ]
         ]   
         ...
    ]
Copier après la connexion
Copier après la connexion
<🎜. >$data [3] = ["id" => 4, "pid" => 3 , "name" => 'Pékin'];

$value = &$data[3];

$tmp [3] = &$data[3];
function buildTreeByReference($data, $id = &#39;id&#39;, $pid = &#39;pid&#39;, $child = "children")
    {
       # $tmp = [];
       # $tree = [];  
        
       # foreach ($data as $key => &$value) {
                // 
                $tmp[$value[&#39;id&#39;]] = &$value;
                
        #        if (!isset($tmp[$value[&#39;pid&#39;]])) {
        #            $tree[] = &$tmp[$value[&#39;id&#39;]];
                }else {
                     $temp = &$tmp[$value[&#39;pid&#39;]];
                     $temp[$child][] = &$value;
                }
                unset($temp, $value);
        }
        return $tree;
    }
Copier après la connexion
Copier après la connexion
Copier après la connexion

Remarque : $temp est &$tmp[2], qui pointe vers la même adresse que $data[1]

Donc $temp['children'][] = &$value, le résultat de l'opération est :
Notez ici :
Il s'agit des $data[2] stockées dans les enfants pendant le troisième cycle La référence de
dans la quatrième boucle est $data[2]['children'][] = &$value, et $value pointe vers $data[3]

, donc le résultat est :



ok À ce stade, tout le processus d'exécution est terminé. Comprenez-vous ? :)

   $data[
        [  
         "id" => 1,
         "pid" => 0 ,
         "name" => &#39;Universe&#39;
         "children"=>[
                       // &$data[1],   //注意:存储的是引用
                         [
                           "id" => 2, 
                           "pid" => 1 ,
                           "name" => &#39;Earth&#39;
                           "children" => [
                                   &data[2] //注意:存储的是引用   
                            ]
                         
                         ] 
                         
                     ]
             ]
         ]   
         ...
    ]
Copier après la connexion
Copier après la connexion
Au fait, il existe une autre méthode, qui est également par référence. Je ne l'analyserai pas. Si vous comprenez la méthode ci-dessus, la suivante est relativement simple.


Recommandations associées :
   $data[
        [  
         "id" => 1,
         "pid" => 0 ,
         "name" => &#39;Universe&#39;
         "children"=>[
                       // &$data[1],   //注意:存储的是引用
                         [
                           "id" => 2, 
                           "pid" => 1 ,
                           "name" => &#39;Earth&#39;
                           "children" => [
                                  // &data[2] //注意:存储的是引用 
                                  [
                                      "id" => 3,
                                      "pid" => 2 ,
                                      "name" => &#39;China&#39; 
                                      "children" =>[
                                                 &$data[3];  //注意:存储的是引用                            
                                      ]
                                  ]  
                            ]
                         
                         ] 
                         
                     ]
             ]
         ]   
         ...
    ]
Copier après la connexion

Un résumé de plusieurs exemples d'utilisation cités par php

                                                

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
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!