この記事では主に PHP 参照の理解を紹介します。これは、特定の参照価値があります。必要な友人はそれを参照できます。
日々の開発では、ツリーを構築する必要があります。 id と pid の関係を使用してツリー構造が構築され、ツリーが走査され、他の操作が実行されます。実装方法は2つあります: 1. 再帰、2. 参照
これら 2 つの方法の長所と短所も明らかです。
再帰は実装が簡単ですが、カウントするデータの量が増えると、パフォーマンスが非常に低下します。
引用の概念自体は理解しやすく、パフォーマンスも非常に優れていますが、それを使いこなすにはまだ一定の敷居があり、書くのは簡単ではありません。
この記事を書いた理由は、最近とても良い解決策に出会って、引用について改めて理解できたからです。この記事を通じて学習結果をまとめてから、コードに直接進みます。
以下のコードを読んで理解できれば、あなたは引用に関して本当に知識があることを意味します。この記事を直接スキップすることもできます。
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; }
OK、最初に他のことについては話さないでください。次のデータを使用してこのメソッドをテストできます。
$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'], ];
追加の注意:このメソッドは、親ノードが前にある必要があるという事実に注意する必要があります。順序付けされていないデータには適していないので、順序付けされていない場合は、最初に並べ替える必要があります。
事故がなければ、印刷結果は次のようになります:
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" } } } } } } } }
それでも理解できない場合, それは構いません、一つずつ分析してみましょう
実際には、これを徹底的に理解する必要があります 解決策には2つの部分を理解する必要があります。
foreach代入原則
引用された原則
foreach
$data = ["student", "teacher"]; foreach ($data as $index => $item) { }
ループするたびに、$data[0]と$data[1]の「値」がコピーされることに注意してください 1 つのコピーを $item に割り当てます
Quote (必ず自分で試してみてください)
$a = 1; $b = &$a; $c = $b; $c = 2; 猜猜看 $b = ?;
リファレンスについて質問がある場合は、クリックしてください
上記の foreach と Reference を理解できれば、これで完了です。この解決策を理解してください。計画のすべての実行プロセスを理解しました。おめでとうございます。まだ問題がある場合でも、問題はありません。ステップごとに分析しましょう。
まず、元の関数を見てみましょう
function buildTreeByReference($data, $id = 'id', $pid = 'pid', $child = "children") { $tmp = []; #以id为健,$value为值的容器,可以很巧妙的判断根节点元素 $tree = []; #利用引用,对$data的数据进行操作 foreach ($data as $key => &$value) { #&$value取到$data元素对应值的引用 $tmp[$value['id']] = &$value; #以$value['id']为键,&$value引用为值push到$tmp中, #这样可以巧妙的判断当前元素是否为根节点 if (!isset($tmp[$value['pid']])) { #将根节点push到$tree中 $tree[] = &$tmp[$value['id']]; }else { #若当前元素的父节点存在于$tmp中, 引用获取$tmp中对应父节点的值 $temp = &$tmp[$value['pid']]; #然后将当前元素push到其父节点的children中 $temp[$child][] = &$value; } #为了不引起变量污染, 引用用完后,需要unset掉 unset($temp, $value); } return $tree; }
function buildTreeByReference($data, $id = 'id', $pid = 'pid', $child = "children") { # $tmp = []; # $tree = []; # 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; }
$tmp[1] = &$data[0];
$tree[ ] = &$data[0]
function buildTreeByReference($data, $id = 'id', $pid = 'pid', $child = "children") { # $tmp = []; # $tree = []; # 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; }
$data[1] = ["id" => 2, "pid" => 1 , "name " => '地球']; $value=&$data[1];
$tmp[2] = &$data[1];
注:
$temp は &$tmp[1]、これは $data[0] と同じポイントを指します。つまり、 $temp['children'][] = &$value 、演算の結果は次のようになります:
$data[ [ "id" => 1, "pid" => 0 , "name" => 'Universe' "children"=>[ &$data[1], //注意:存储的是引用 ] ] ... ]
function buildTreeByReference($data, $id = 'id', $pid = 'pid', $child = "children") { # $tmp = []; # $tree = []; # 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; }
変数。状況:
$data[2] = ["id" => 3、"pid" => 2、"name" => '中国'];$value = &$data[2]; $tmp[3] = &$data[2];
注:
$temp は $data[1] と同じアドレスを指します したがって、$temp['children' ][] = &$value、操作の結果は次のとおりです:
ここで注意してください:
$data[ [ "id" => 1, "pid" => 0 , "name" => 'Universe' "children"=>[ &$data[1], //注意:存储的是引用 ] ] ... ]
$data[ [ "id" => 1, "pid" => 0 , "name" => 'Universe' "children"=>[ // &$data[1], //注意:存储的是引用 [ "id" => 2, "pid" => 1 , "name" => 'Earth' "children" => [ &data[2] //注意:存储的是引用 ] ] ] ] ] ... ]
5 4 番目のループ
function buildTreeByReference($data, $id = 'id', $pid = 'pid', $child = "children") { # $tmp = []; # $tree = []; # 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; }
変数の状況:
$data[3] = ["id" => 3 、"name" => '北京'];$value = &$data[3];$tmp[ 3] = &$data[3];
注:
$temp は &$tmp[2] で、$data[1]と同じアドレスを指します。したがって、$temp['children'][] = &$value、演算の結果は次のとおりです:
こちら 注:
$data[ [ "id" => 1, "pid" => 0 , "name" => 'Universe' "children"=>[ // &$data[1], //注意:存储的是引用 [ "id" => 2, "pid" => 1 , "name" => 'Earth' "children" => [ &data[2] //注意:存储的是引用 ] ] ] ] ] ... ]
ちなみに、別の方法もありますが、これも参考にしません。上記の方法を理解していれば、次の方法は比較的簡単です。
rreee
で引用されたいくつかの使用例の要約
以上がPHP リファレンスを再理解するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。