Maison > développement back-end > tutoriel php > PHP utilise une méthode récursive pour obtenir une classification infinie

PHP utilise une méthode récursive pour obtenir une classification infinie

大家讲道理
Libérer: 2023-03-05 18:10:02
original
2398 Les gens l'ont consulté

Je pense que de nombreux amis voudront créer un site Web pour améliorer leurs compétences lors de l'apprentissage de PHP, comme les sites Web d'entreprise et les sites Web de centres commerciaux. Leurs dernières fonctions et gestion de colonnes utilisent une méthode de classification illimitée, nous explorerons ensuite sa mise en œuvre approfondie. logique en étudiant la technologie de classification à niveaux infinis.

Qu'est-ce que la classification infinie ?

La classification à niveau infini est une technique de classification. Par exemple, la classification à niveau infini est couramment utilisée dans l'organisation des départements, la classification des articles, la classification des sujets, etc. . En fait, si l'on y réfléchit bien, il y a tout simplement trop de classifications dans la vie. Les vêtements peuvent être divisés en vêtements pour hommes et vêtements pour femmes, hauts et pantalons, et ils peuvent également être classés selon les groupes d'âge. La classification est partout, et la classification apparaît « infinie ». Je ne parlerai pas ici de la nécessité d’une classification infinie.

Introduction au principe de la classification infinie

La classification infinie peut paraître "élevée", mais en fait le principe est très simple. La classification illimitée nécessite non seulement l'ingéniosité du code, mais repose également sur la rationalité de la conception de la base de données. Pour satisfaire une classification infinie, la base de données doit avoir deux champs nécessaires, id et pid. L'identifiant est utilisé pour s'identifier, tandis que le pid est utilisé pour indiquer l'identifiant parent. En d’autres termes, chaque enregistrement de classification ne se décrit pas seulement lui-même, mais décrit également un autre identifiant qui le concerne le plus. Ce qui semblait être une question compliquée a été résolu avec une si petite astuce.

Instance

Base de données de construction

Nom de la table : catégorie

id int clé primaire, incrémentation automatique

name varchar nom de la catégorie

ID de classe parent pid int, par défaut 0

Le pid par défaut de la catégorie supérieure est 0. Lorsque nous voulons supprimer l'arborescence des sous-catégories d'une certaine catégorie, l'idée de base est la récursivité. Bien entendu, pour des raisons d'efficacité, il n'est pas recommandé d'interroger la base de données pour chaque récursion. L'approche habituelle consiste à d'abord tout récupérer. catégories et enregistrez-les dans un tableau PHP, puis traitez-le et enfin mettez en cache les résultats pour améliorer l'efficacité de la requête suivante.
Construisez d'abord un tableau original, qui peut être extrait directement de la base de données :

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

Le but est de le convertir dans la structure suivante
Ordinateur - Ordinateur portable - Ultrabook - Ordinateur portable de jeu - Téléphone mobile de bureau - Smartphone - Machine fonctionnelle
S'il est représenté par un tableau, vous pouvez ajouter une clé enfant pour stocker ses sous-catégories :

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(
                    //此处省略
                )
            ),
        )
    ),
    //其他分类省略
)
Copier après la connexion

Processus de traitement :

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

Les résultats d'impression sont les suivants :

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

Avantages : La relation est claire, et il est simple de modifier la relation supérieur-subordonné.

Inconvénients : en utilisant PHP pour traiter, si le nombre de catégories est énorme, l'efficacité sera également réduite.


Extension-------Fonction récursive

 Fonction récursive est un type de fonction que nous utilisons couramment. La fonctionnalité la plus basique est que la fonction s'appelle elle-même, mais elle doit être jugée conditionnellement avant de s'appeler, sinon elle continuera à l'être. appelé indéfiniment. Quelles méthodes peuvent être utilisées pour implémenter des fonctions récursives ? Cet article répertorie trois méthodes de base. Le comprendre nécessite un certain nombre de connaissances de base, notamment une compréhension des variables globales, des références, des variables statiques et une compréhension de leur portée. Les fonctions récursives sont également une bonne technique pour résoudre des niveaux infinis de classification. Si vous êtes intéressé par la classification infinie, veuillez vous référer à PHP pour utiliser des fonctions récursives afin d'obtenir une classification infinie. J'ai l'habitude d'expliquer des vérités complexes en termes simples. Si vous ne comprenez vraiment pas, veuillez vous référer au manuel.

 Utiliser des références comme paramètres

Que les références soient des paramètres ou non, vous devez d'abord comprendre ce qu'est une référence ? Une référence signifie simplement que deux variables portant des noms différents pointent vers la même adresse de stockage. À l'origine, chaque variable avait sa propre adresse de stockage, et l'affectation et la suppression se déroulaient selon leur propre chemin. Bon maintenant, les deux variables partagent une adresse de stockage. $a=&$b; Cela signifie en réalité que $a doit partager une pièce avec $b quelle que soit son adresse de stockage d'origine. Par conséquent, toute modification de la valeur de l'adresse stockée affectera les deux valeurs. ​

Les fonctions font à l'origine leur propre travail, même s'il s'agit de fonctions portant le même nom. Les fonctions récursives envisagent de prendre des références comme paramètres et de devenir un pont pour former un partage de données entre deux fonctions. Bien que les deux fonctions semblent fonctionner sur des adresses différentes, elles opèrent en réalité sur la même adresse mémoire.

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

}
Copier après la connexion


  上面的例子非常简答,以a<10作为判断条件,条件成立,则把a<10作为判断条件,条件成立,则把a赋给result[];将result[];将result的引用传入函数,会将每一次递归产生的a添加到结果数组a添加到结果数组result。因而本例生成的$result数组是 Array ( [0] => 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;
}
Copier après la connexion


  利用静态变量

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

例子:

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

$count++;
}
test();
test();
test();
test();
test();
Copier après la connexion


  请问这一段代码的执行结果是多少?是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;
}
Copier après la connexion

  总结

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

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

        test($a);
    }
}
Copier après la connexion

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

相关文章:

php递归实现无限级分类树

揭露php无限级分类的原理

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

É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