Heim  >  Artikel  >  Backend-Entwicklung  >  PHP verwendet eine rekursive Methode, um eine unendliche Klassifizierung zu erreichen

PHP verwendet eine rekursive Methode, um eine unendliche Klassifizierung zu erreichen

大家讲道理
大家讲道理Original
2017-03-25 13:29:122363Durchsuche

Ich glaube, dass viele Freunde eine Website erstellen möchten, um ihre Fähigkeiten beim Erlernen von PHP zu verbessern, wie z. B. Unternehmenswebsites und Einkaufszentren-Websites. Ihre neuesten Funktionen und die Spaltenverwaltung verwenden eine unbegrenzte Klassifizierungsmethode. Als nächstes werden wir deren umfassende Implementierung untersuchen Logik durch Erlernen der Klassifizierungstechnologie auf unendlicher Ebene.

Was ist eine unendliche Klassifizierung?

Die Klassifizierung auf unendlicher Ebene ist eine Klassifizierungstechnik. Beispielsweise wird die Klassifizierung auf unendlicher Ebene häufig in der Abteilungsorganisation, der Artikelklassifizierung, der Themenklassifizierung usw. verwendet. Sie kann einfach als Klassifizierung verstanden werden . Wenn wir genau darüber nachdenken, gibt es im Leben einfach zu viele Klassifizierungen: Kleidung kann in Herrenbekleidung und Damenbekleidung, Oberteile und Hosen unterteilt werden, und sie können auch nach Altersgruppen klassifiziert werden. Klassifizierung ist überall und Klassifizierung erscheint „unendlich“. Ich werde hier nicht über die Notwendigkeit einer unendlichen Klassifizierung sprechen.

Einführung in das Prinzip der unendlichen Klassifizierung

Die unendliche Klassifizierung mag „hochgesteckt“ erscheinen, aber tatsächlich ist das Prinzip sehr einfach. Die unendliche Klassifizierung erfordert nicht nur den Einfallsreichtum des Codes, sondern auch die Rationalität des Datenbankdesigns. Um die unendliche Klassifizierung zu erfüllen, muss die Datenbank über zwei erforderliche Felder verfügen: id und pid. Die ID wird verwendet, um sich selbst zu identifizieren, während die PID verwendet wird, um die übergeordnete ID anzugeben. Mit anderen Worten: Jeder Klassifizierungsdatensatz beschreibt nicht nur sich selbst, sondern auch eine andere ID, um die er sich am meisten kümmert. Was wie eine komplizierte Angelegenheit schien, wurde mit so einem kleinen Trick gelöst.

Instanz

Gebäudedatenbank

Tabellenname: Kategorie

id int Primärschlüssel, automatische Inkrementierung

Name Varchar Kategoriename

pid int übergeordnete Klassen-ID, Standard 0

Die Standard-PID der obersten Kategorie ist 0. Wenn wir den Unterkategoriebaum einer bestimmten Kategorie herausnehmen möchten, ist die Grundidee die Rekursion. Aus Effizienzgründen wird natürlich nicht empfohlen, die Datenbank bei jeder Rekursion abzufragen. Der übliche Ansatz besteht darin, zuerst alle abzurufen Kategorien und speichern Sie sie in einem PHP-Array, verarbeiten Sie sie und speichern Sie sie schließlich zwischen, um die Effizienz der nächsten Anfrage zu verbessern.
Erstellen Sie zunächst ein Original-Array, das direkt aus der Datenbank abgerufen werden kann:

$categories = array(
    array('id'=>1,'name'=>'电脑','pid'=>0),
    array('id'=>2,'name'=>'手机','pid'=>0),
    array('id'=>3,'name'=>'笔记本','pid'=>1),
    array('id'=>4,'name'=>'台式机','pid'=>1),
    array('id'=>5,'name'=>'智能机','pid'=>2),
    array('id'=>6,'name'=>'功能机','pid'=>2),
    array('id'=>7,'name'=>'超级本','pid'=>3),
    array('id'=>8,'name'=>'游戏本','pid'=>3),
)

Das Ziel besteht darin, es in die folgende Struktur umzuwandeln
Computer - Notebook - Ultrabook - Gaming-Laptop - Desktop-Mobiltelefon - Smartphone - Funktionsmaschine
Wenn durch ein Array dargestellt, können Sie einen Kinderschlüssel hinzufügen, um seine Unterkategorien zu speichern:

array(
    //1对应id,方便直接读取
    1 => array(
        'id'=>1,
        'name'=>'电脑',
        'pid'=>0,
        children=>array(
            &array(
                'id'=>3,
                'name'=>'笔记本',
                'pid'=>1,
                'children'=>array(
                    //此处省略
                )
            ),
            &array(
                'id'=>4,
                'name'=>'台式机',
                'pid'=>1,
                'children'=>array(
                    //此处省略
                )
            ),
        )
    ),
    //其他分类省略
)

Verarbeitungsprozess:

$tree = array();
//第一步,将分类id作为数组key,并创建children单元
foreach($categories as $category){
    $tree[$category['id']] = $category;
    $tree[$category['id']]['children'] = array();
}
//第二部,利用引用,将每个分类添加到父类children数组中,这样一次遍历即可形成树形结构。
foreach ($tree as $k=>$item) {
    if ($item['pid'] != 0) {
        $tree[$item['pid']]['children'][] = &$tree[$k];
    }
}
print_r($tree);

Die Druckergebnisse sind wie folgt:

Array(
    [1] => Array
        (
            [id] => 1
            [name] => 电脑
            [pid] => 0
            [children] => Array
                (
                    [0] => Array
                        (
                            [id] => 3
                            [name] => 笔记本
                            [pid] => 1
                            [children] => Array
                                (
                                    [0] => Array
                                        (
                                            [id] => 7
                                            [name] => 超级本
                                            [pid] => 3
                                            [children] => Array
                                                (
                                                )
                                        )
                                    [1] => Array
                                        (
                                            [id] => 8
                                            [name] => 游戏本
                                            [pid] => 3
                                            [children] => Array
                                                (
                                                )
                                        )
                                )
                        )
                    [1] => Array
                        (
                            [id] => 4
                            [name] => 台式机
                            [pid] => 1
                            [children] => Array
                                (
                                )
                        )
                )
        )
    [2] => Array
        (
            [id] => 2
            [name] => 手机
            [pid] => 0
            [children] => Array
                (
                    [0] => Array
                        (
                            [id] => 5
                            [name] => 智能机
                            [pid] => 2
                            [children] => Array
                                (
                                )
                        )
                    [1] => Array
                        (
                            [id] => 6
                            [name] => 功能机
                            [pid] => 2
                            [children] => Array
                                (
                                )
                        )
                )
        )
    [3] => Array
        (
            [id] => 3
            [name] => 笔记本
            [pid] => 1
            [children] => Array
                (
                    [0] => Array
                        (
                            [id] => 7
                            [name] => 超级本
                            [pid] => 3
                            [children] => Array
                                (
                                )
                        )
                    [1] => Array
                        (
                            [id] => 8
                            [name] => 游戏本
                            [pid] => 3
                            [children] => Array
                                (
                                )
                        )
                )
        )
    [4] => Array
        (
            [id] => 4
            [name] => 台式机
            [pid] => 1
            [children] => Array
                (
                )
        )
    [5] => Array
        (
            [id] => 5
            [name] => 智能机
            [pid] => 2
            [children] => Array
                (
                )
        )
    [6] => Array
        (
            [id] => 6
            [name] => 功能机
            [pid] => 2
            [children] => Array
                (
                )
        )
    [7] => Array
        (
            [id] => 7
            [name] => 超级本
            [pid] => 3
            [children] => Array
                (
                )
        )
    [8] => Array
        (
            [id] => 8
            [name] => 游戏本
            [pid] => 3
            [children] => Array
                (
                )
        )
)

Vorteile: Die Beziehung ist klar und es ist einfach, die Beziehung zwischen Vorgesetzten und Untergebenen zu ändern.

Nachteile: Wenn PHP für die Verarbeitung verwendet wird, verringert sich auch die Effizienz, wenn die Anzahl der Kategorien sehr groß ist.


Erweiterung-------Rekursive Funktion

 Rekursive Funktion ist eine Art von Funktion, die wir häufig verwenden. Das grundlegendste Merkmal ist, dass die Funktion sich selbst aufruft, aber sie muss vor dem Aufruf bedingt beurteilt werden, sonst bleibt sie bestehen auf unbestimmte Zeit angerufen. Mit welchen Methoden können rekursive Funktionen implementiert werden? In diesem Artikel werden drei grundlegende Möglichkeiten aufgeführt. Um es zu verstehen, ist ein gewisses Maß an Grundwissen erforderlich, einschließlich des Verständnisses globaler Variablen, Referenzen und statischer Variablen sowie des Verständnisses ihres Umfangs. Rekursive Funktionen sind auch eine gute Technik zur Lösung unendlicher Klassifizierungsebenen. Wenn Sie an einer unendlichen Klassifizierung interessiert sind, lesen Sie bitte PHP, um mithilfe rekursiver Funktionen eine unendliche Klassifizierung zu erreichen. Ich bin es gewohnt, komplexe Wahrheiten in Laienbegriffen zu erklären. Wenn Sie es wirklich nicht verstehen, schauen Sie bitte im Handbuch nach.

 Referenzen als Parameter verwenden

Unabhängig davon, ob Referenzen Parameter sind oder nicht, müssen Sie zunächst verstehen, was eine Referenz ist? Eine Referenz bedeutet einfach, dass zwei Variablen mit unterschiedlichen Namen auf dieselbe Speicheradresse verweisen. Ursprünglich hatte jede Variable ihre eigene Speicheradresse und das Zuweisen und Löschen verlief auf eigene Weise. Okay, jetzt teilen sich die beiden Variablen eine Speicheradresse. $a=&$b; Was es tatsächlich bedeutet, ist, dass $a unabhängig von seiner ursprünglichen Speicheradresse einen Raum mit $b teilen muss. Daher wirkt sich jede Änderung des gespeicherten Adresswerts auf beide Werte aus. ​

Funktionen erledigen ursprünglich ihre eigene Sache, auch wenn es sich um Funktionen mit demselben Namen handelt. Rekursive Funktionen berücksichtigen Referenzen als Parameter und werden zu einer Brücke, um den Datenaustausch zwischen zwei Funktionen zu bilden. Obwohl die beiden Funktionen scheinbar an unterschiedlichen Adressen arbeiten, arbeiten sie tatsächlich an derselben Speicheradresse.

function test($a=0,&$result=array()){
$a++;
if ($a<10) {
    $result[]=$a;
    test($a,$result);
}
echo $a;
return $result;

}


  上面的例子非常简答,以a24d95045695e230a5d2810e8df9c2cf0 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 [6] => 7 [7] => 8 [8] => 9 ) 。

本例比较有意思的是echo a的值。相信很多人认为是12345678910吧,其实不然,是1098765432。为什么呢?因为函数还没执行echoa的值。相信很多人认为是12345678910吧,其实不然,是1098765432。为什么呢?因为函数还没执行echoa前就进行了下一次的函数递归。真正执行echo a是当a是当a<10条件不满足的时候,echo a,返回a,返回result,对于上一层而言,执行完递归函数,开始执行本层的echo $a,依次类推。 

  利用全局变量

  利用全局变量完成递归函数,请确保你确实理解什么是全局变量。global在函数内申明变量不过是外部变量的同名引用。变量的作用范围仍然在本函数范围内。改变这些变量的值,外部同名变量的值自然也改变了。但一旦用了&,同名变量不再是同名引用。利用全局变量实现递归函数没必要理解到这么深的一层,还保持原有对全局变量的看法就可以顺理成章理解递归函数。

function test($a=0,$result=array()){
    global $result;
    $a++;
    if ($a<10) {
        $result[]=$a;
        test($a,$result);
    }
    return $result;
}


  利用静态变量

  我们常常在类中见到static,今天我们把它利用到递归函数中。请记住static的作用:仅在第一次调用函数的时候对变量进行初始化,并且保留变量值。

例子:

function test(){
static $count=0;
echo $count;

$count++;
}
test();
test();
test();
test();
test();


  请问这一段代码的执行结果是多少?是00000么?必然不是。是01234。首先第一次调用test(),static对 $count 进行初始化,其后每一次执行完都会保留 $count 的值,不再进行初始化,相当于直接忽略了 static$count=0; 这一句。

  因而将static应用到递归函数作用可想而知。在将需要作为递归函数间作为“桥梁"的变量利用static进行初始化,每一次递归都会保留"桥梁变量"的值。

function test($a=0){
    static $result=array();
    $a++;
    if ($a<10) {
        $result[]=$a;
        test($a);
    }
    return $result;
}

  总结

  所谓递归函数,重点是如何处理函数调用自身是如何保证所需要的结果得以在函数间合理"传递",当然也有不需要函数之间传值得递归函数,例如:

function test($a=0){
    $a++;
    if ($a<10) {
        echo $a;

        test($a);
    }
}

面对这样的函数,深入理解变量引用相关知识对解决这类问题大有裨益。

相关文章:

php递归实现无限级分类树

揭露php无限级分类的原理

php无限级分类实现方法分析

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn