>  기사  >  백엔드 개발  >  PHP는 재귀적 방법을 사용하여 무한 분류를 달성합니다.

PHP는 재귀적 방법을 사용하여 무한 분류를 달성합니다.

大家讲道理
大家讲道理원래의
2017-03-25 13:29:122351검색

많은 친구들이 기업 웹사이트, 쇼핑몰 웹사이트 등 PHP를 배울 때 자신의 능력을 향상시키기 위해 웹사이트를 만들고 싶어할 것이라고 믿습니다. 최신 기능과 열 관리는 무제한 분류 방법을 사용하므로 다음에는 심층적인 구현을 살펴보겠습니다. 무한 수준의 분류 기술을 연구하여 논리학을 연구합니다.

무한분류란 무엇인가요?

무한급 분류는 분류기법의 일종으로, 예를 들어 무한급 분류는 부서 구성, 기사 분류, 주제 분류 등에서 흔히 사용됩니다. 간단히 분류라고 이해하면 됩니다. . 사실 생각해보면 인생에는 분류가 너무 많다. 옷은 남성복과 여성복, 상의와 바지로 나눌 수 있고, 연령별로도 분류할 수 있다. 분류는 어디에나 있으며 분류는 "무한"으로 나타납니다. 여기서는 무한 분류의 필요성에 대해 이야기하지 않겠습니다.

무한 분류 원리 소개

무한 분류는 겉보기에는 "고상해" 보이지만 사실 원리는 매우 간단합니다. 무한 분류에는 코드의 독창성이 필요할 뿐만 아니라 데이터베이스 설계의 합리성이 필요합니다. 무한 분류를 충족하려면 데이터베이스에 id와 pid라는 두 개의 필수 필드가 있어야 합니다. id는 자신을 식별하는 데 사용되고 pid는 부모 ID를 나타내는 데 사용됩니다. 즉, 각 분류 레코드는 자신을 설명할 뿐만 아니라 가장 밀접하게 관련된 다른 ID도 설명합니다. 복잡해 보이던 문제가 이런 작은 트릭으로 해결되었습니다.

인스턴스

데이터베이스 구축

테이블 이름: 카테고리

id int 기본 키, 자동 증가

name varchar 카테고리 이름

pid int 상위 클래스 ID, 기본값 0

최상위 카테고리의 기본 pid는 0입니다. 특정 카테고리의 하위 카테고리 트리를 꺼내려는 경우 기본 아이디어는 재귀입니다. 물론 효율성 문제로 인해 모든 재귀에 대해 데이터베이스를 쿼리하는 것은 권장되지 않습니다. 카테고리를 지정하고 이를 PHP 배열에 저장한 후 처리하고 마지막으로 결과를 캐시하여 다음 요청의 효율성을 향상시킵니다.
먼저 데이터베이스에서 직접 가져올 수 있는 원본 배열을 구축합니다.

$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),
)

목표는 이를 다음 구조로 변환하는 것입니다.
컴퓨터 - 노트북 - 울트라북 - 게임 노트북 - 데스크탑 휴대폰 - 스마트폰 - 기능 머신
배열로 표시되는 경우 하위 카테고리를 저장하기 위한 하위 키를 추가할 수 있습니다:

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(
                    //此处省略
                )
            ),
        )
    ),
    //其他分类省略
)

처리 프로세스:

$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);

인쇄 결과는 다음과 같습니다.

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
                (
                )
        )
)

장점: 관계가 명확하고, 상하 관계 수정이 간단합니다.

단점: 처리에 PHP를 사용하면 카테고리 수가 많으면 효율성도 떨어집니다.


확장-------재귀함수

 재귀함수는 우리가 흔히 사용하는 함수의 일종으로 가장 기본적인 특징은 함수가 자신을 호출하는데, 자신을 호출하기 전에 조건부로 판단해야 하며, 그렇지 않으면 호출이 무한정 계속된다는 것입니다. 재귀 함수를 구현하는 데 어떤 방법을 사용할 수 있습니까? 이 문서에서는 세 가지 기본 방법을 나열합니다. 이를 이해하려면 전역 변수, 참조, 정적 변수에 대한 이해 및 해당 범위에 대한 이해를 포함하여 일정량의 기본 지식이 필요합니다. 재귀 함수는 무한 수준의 분류를 해결하는 데에도 좋은 기술입니다. 무한 분류에 관심이 있다면 PHP를 참조하여 재귀 함수를 사용하여 무한 분류를 달성하세요. 나는 일반인의 용어로 복잡한 진리를 설명하는 데 익숙합니다. 정말로 이해가 되지 않으면 설명서를 참조하십시오.

 참조를 매개변수로 사용

참조가 매개변수인지 아닌지에 관계없이 참조가 무엇인지 먼저 이해해야 합니까? 참조는 단순히 이름이 다른 두 변수가 동일한 저장 주소를 가리키는 것을 의미합니다. 원래 각 변수에는 고유한 저장 주소가 있었고 할당과 삭제는 고유한 방식으로 진행되었습니다. 좋습니다. 이제 두 변수는 저장 주소를 공유합니다. $a=&$b; 실제로 의미하는 바는 $a가 원래 저장 주소에 관계없이 $b와 방을 공유해야 한다는 것입니다. 따라서 저장된 주소 값을 변경하면 두 값 모두에 영향을 미칩니다. ​

같은 이름을 가진 함수라도 함수는 원래 자신의 일을 합니다. 재귀 함수는 참조를 매개 변수로 사용하고 두 함수 간의 데이터 공유를 형성하는 브리지가 되는 것을 고려합니다. 두 함수는 서로 다른 주소에서 작동하는 것처럼 보이지만 실제로는 동일한 메모리 주소에서 작동합니다.

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无限级分类实现方法分析

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.