PHP를 배우는 많은 친구들이 실력을 향상시키기 위한 방법으로 온라인 쇼핑몰을 구축하려고 노력할 것이라고 믿습니다. 제품 분류, 제품 이름 등에 대한 다양한 작업에 익숙해지면 무제한 분류 목록을 만들어 볼 수 있습니다.
인터넷에서 PHP 인피니투스(Infinitus) 분류를 검색해 보면 많은데 똑같은 내용도 많습니다. 게다가 글도 너무 지저분하고 코드도 많아서 믿을 수 없는 내용입니다. 우리는 인피니투스 분류를 스스로 수정해야 합니다.
무한분류란 무엇인가요?
무한급 분류는 분류기법입니다. 예를 들어 부서 구성, 기사 분류, 주제 분류 등은 흔히 무한급 분류로 이해하면 됩니다. 사실 생각해보면 인생에는 분류가 너무 많다. 옷은 남성복과 여성복, 상의와 바지로 나눌 수 있고, 연령별로도 분류할 수 있다. 분류는 어디에나 있으며 분류는 "무한"으로 나타납니다. 여기서는 무한 분류의 필요성에 대해 이야기하지 않겠습니다.
무한분류의 원리 소개
무한 분류는 '고급'처럼 보이지만 사실 원리는 매우 간단합니다. 무한 분류에는 코드의 독창성이 필요할 뿐만 아니라 데이터베이스 설계의 합리성이 필요합니다. 무한 분류를 충족하려면 데이터베이스에 id와 pid라는 두 개의 필수 필드가 있어야 합니다. id는 자신을 식별하는 데 사용되고 pid는 부모 ID를 나타내는 데 사용됩니다. 즉, 각 분류 레코드는 자신을 설명할 뿐만 아니라 가장 밀접하게 관련된 다른 ID도 설명합니다. 복잡해 보이던 문제가 이런 작은 트릭으로 해결되었습니다.
더 이상 고민하지 말고 이제 이 기사의 예를 보여드리겠습니다.
저는 열렬한 해적 팬으로서 이 글에서는 '원피스'의 캐릭터 구성을 예로 들어보겠습니다.
데이터베이스 준비:
테이블 일체형 제작:
create table onepiece( id int auto_increment, pid int not null, name varchar(225) not null, primary key(id) );
테스트 데이터 삽입:
insert onepiece values (1,0,'海军'), (2,0,'海贼'), (3,0,'革命军'), (4,1,'青雉'), (5,1,'赤犬'), (6,1,'黄猿'), (7,2,'四皇'), (8,2,'七武海'), (9,2,'草帽海贼团'), (10,9,'索隆'), (11,7,'香克斯'), (12,8,'多弗朗明哥'), (13,8,'克洛克达尔');
대중과학을 기반으로 한 원피스의 배경은 다음과 같습니다. 세계는 해군, 해적, 혁명군의 세 가지 주요 진영으로 나뉩니다. 해군에는 아오키지, 아카이누, 키자루 장군이 있습니다. 해적에는 사천황, 칠부회, 밀짚모자 해적단이 포함됩니다. 사천왕에는 샹크스가 있고, 칠부회에는 도플라밍고와 악어가 있고, 밀짚모자 해적단에는 조로가 있습니다. (광고: 원피스는 정말 좋습니다.)
최종 목표 :
오늘 만들어볼 것은 무한분류형식 2가지인데, 하나는 드롭다운 리스트형이고, 또 하나는 네비게이션 링크형입니다. 렌더링이 직접 업로드됩니다:
드롭다운 목록 공식
탐색 링크 스타일
예제 코드:
diaplayList()를 호출하여 드롭다운 목록 양식을 표시하고 diaplayLink를 호출하여 탐색 링크 카테고리를 표시하도록 Unlimited 클래스를 캡슐화했습니다. 범주를 추가(addNodes())하고 삭제(deleteNodes)할 수도 있습니다.
<?php class Unlimited{ protected $mysqli; public function __construct($config){ $this->mysqli=new mysqli($config['host'],$config['user'],$config['pwd']); $this->mysqli->select_db($config['db']); $this->mysqli->set_charset('utf8'); if ($this->mysqli->connect_errno) { echo $this->mysqli->connect_error; } } private function getList($pid=0,&$result=array(),$spac=0){ $spac=$spac+2; $sql="select * from onepiece where pid={$pid}"; $rs=$this->mysqli->query($sql); while($row=$rs->fetch_assoc()) { $row['name']=str_repeat('  ',$spac).$row['name']; $result[]=$row; $this->getList($row['id'],$result,$spac); } return $result; } /** * 展现下拉列表式分类 * @return [type] */ public function displayList(){ $rs=$this->getList(); $str="<select name='cate'>"; foreach ($rs as $key => $val) { $str.="<option >{$val['name']}</option>"; } $str.="</select>"; return $str; } private function getLink($cid,&$result=array()){ $sql="select * from onepiece where id={$cid}"; $rs=$this->mysqli->query($sql); if($row=$rs->fetch_assoc()){ $result[]=$row; $this->getLink($row['pid'],$result); } return array_reverse($result); } /** * 展现导航Link * @param [type] $cid [description] * @return [type] [description] */ public function displayLink($cid){ $rs=$this->getLink($cid); $str=''; foreach ($rs as $val) { $str.="<a href=''>{$val['name']}</a>>"; } return $str; } /** * 增加分类 * @param [type] $pid 父类id * @param [type] $name 本类名 */ public function addNodes($pid,$name){ $sql="insert into onepiece values('',{$pid},'".$name."')"; if($this->mysqli->query($sql)){ return true; } } /** * 删除分类 * @param [type] $id 本类id * @return [type] */ public function deleteNodes($id){ $sql="select * from onepiece where pid ={$id}"; $rs=$this->mysqli->query($sql); if($row=$rs->fetch_assoc()){ $mes="还有子元素,请勿删除"; }else{ $sql="delete from onepiece where id={$id}"; if($this->mysqli->query($sql)){ $mes="删除成功"; } } return $mes; } }
수업에서 다루는 함수는 주로 재귀함수 방식을 채택하고 있습니다. 재귀함수를 깊이 이해하면 나머지는 자연스럽게 이해될 것입니다. 이후 섹션에서 재귀 함수를 구현하는 세 가지 방법을 자세히 설명하겠습니다.
또 다른 예를 살펴보겠습니다.
먼저 분류 정보 테이블을 만듭니다.
CREATE TABLE IF NOT EXISTS `category` ( `categoryId` smallint(5) unsigned NOT NULL AUTO_INCREMENT, `parentId` smallint(5) unsigned NOT NULL DEFAULT '0', `categoryName` varchar(50) NOT NULL, PRIMARY KEY (`categoryId`) ) ;
일부 데이터 삽입:
INSERT INTO `category` (`categoryId`, `parentId`, `categoryName`) VALUES (1, 0, 'php'), (2, 0, 'java'), (3, 0, 'c/c++'), (4, 1, 'php基础'), (5, 1, 'php开源资料'), (6, 1, 'php框架'), (7, 2, 'java Se'), (8, 2, 'java EE'), (9, 2, 'java Me'), (10, 3, 'c/c++基础编程'), (11, 3, 'c/c++系统开发'), (12, 3, 'c嵌入式编程'), (13, 3, 'c++应用开发'), (14, 13, 'c++桌面应用开发'), (15, 13, 'c++游戏开发');
다음은 PHP 코드입니다.
<?php /* php无限极分类 */ //获取某分类的直接子分类 function getSons($categorys,$catId=0){ $sons=array(); foreach($categorys as $item){ if($item['parentId']==$catId) $sons[]=$item; } return $sons; } //获取某个分类的所有子分类 function getSubs($categorys,$catId=0,$level=1){ $subs=array(); foreach($categorys as $item){ if($item['parentId']==$catId){ $item['level']=$level; $subs[]=$item; $subs=array_merge($subs,getSubs($categorys,$item['categoryId'],$level+1)); } } return $subs; } //获取某个分类的所有父分类 //方法一,递归 function getParents($categorys,$catId){ $tree=array(); foreach($categorys as $item){ if($item['categoryId']==$catId){ if($item['parentId']>0) $tree=array_merge($tree,getParents($categorys,$item['parentId'])); $tree[]=$item; break; } } return $tree; } //方法二,迭代 function getParents2($categorys,$catId){ $tree=array(); while($catId != 0){ foreach($categorys as $item){ if($item['categoryId']==$catId){ $tree[]=$item; $catId=$item['parentId']; break; } } } return $tree; } //测试 部分 $pdo=new PDO('mysql:host=localhost;dbname=test','root','8888'); $stmt=$pdo->query("select * from category order by categoryId"); $categorys=$stmt->fetchAll(PDO::FETCH_ASSOC); $result=getSons($categorys,1); foreach($result as $item) echo $item['categoryName'].'<br>'; echo '<hr>'; $result=getSubs($categorys,0); foreach($result as $item) echo str_repeat(' ',$item['level']).$item['categoryName'].'<br>'; echo '<hr>'; $result=getParents($categorys,7); foreach($result as $item) echo $item['categoryName'].' >> '; echo '<hr>'; $result=getParents2($categorys,15); foreach($result as $item) echo $item['categoryName'].' >> '; ?>
최종 결과를 살펴보겠습니다
이 기사에서는 재귀를 사용한 무한 분류를 소개하지만 실제로 모든 사람에게 권장되는 것은 아닙니다. 분류가 많을수록 재귀의 효율성이 떨어집니다. 이 기사는 단지 모든 사람을 더 좋게 만들기 위한 것입니다. 재귀를 이해함으로써 수행됩니다.