假設(shè)你系統(tǒng)里數(shù)據(jù)庫(kù)請(qǐng)求的函數(shù)是 pdo_query (你自己根據(jù)情況調(diào)整),表名是tblcate
創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的繁昌網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
另外,這段代碼使用到了array_column函數(shù),該函數(shù)從php5.5起才有,如果你的版本較低,要找一個(gè)兼容函數(shù)放到函數(shù)庫(kù)里(官方文檔評(píng)論中就有實(shí)現(xiàn))
以下是代碼文本 如果復(fù)制過(guò)去出現(xiàn)T_VARIABLE錯(cuò)誤,就是代碼中字符被系統(tǒng)混掉了,你要重新手打一下
//這里根據(jù)你的意思,應(yīng)該是選出沒(méi)有下級(jí)的節(jié)點(diǎn),如果需要全部或其它的,你根據(jù)情況修改,不影響后面的其它操作
$selectedNodes = pdo_query("select * from tblcate where pid not in(select pid from tblcate)");
//選出全部節(jié)點(diǎn)
$allNodes =?pdo_query("select * from?tblcate ");
//將節(jié)點(diǎn)數(shù)據(jù)使用id索引,方便獲取
$allNodes = array_column($allNodes, NULL, 'id');
foreach($selectedNodes as $node){
$tree =?getParentNode($node['pid']);
//這里的$tree 是上級(jí)名稱(chēng)拼起來(lái)的,不包含本級(jí)名稱(chēng),如要包含,在后面附加上就行了
$node['tree'] = implode(',',$tree);
}
unset($node);
var_export($selectedNodes?);
function getParentNode($pid){
global $allNodes;
$pnodes=[];
if($pid 0 isset($allNodes[$pid])){
$pNode =?$allNodes[$pid];
$pnodes[]= $pNode['name'];
$rnodes =?getParentNode($pNode['pid']);
if(!empty($rnodes)){
$pnodes = array_merge($pnodes,$rnodes);
}
}
return $pnodes;
}
你這種表結(jié)構(gòu)叫鄰接表,查詢的方式通過(guò)自連接。如
SELECT?t1.name?AS?lev1,?t2.name?as?lev2,?t3.name?as?lev3,?t4.name?as?lev4
FROM?Tbname?AS?t1
LEFT?JOIN?Tbname?AS?t2?ON?t2.pid?=?t1.id
LEFT?JOIN?Tbname?AS?t3?ON?t3.pid?=?t2.id
LEFT?JOIN?Tbname?AS?t4?ON?t4.pid?=?t3.id
WHERE?t1.name?=?'XXXX'
這種方法的主要局限是你需要為每層數(shù)據(jù)添加一個(gè)自連接,隨著層次的增加,自連接
變得越來(lái)越復(fù)雜,檢索的性能自然而然的也就下降了。當(dāng)然這種結(jié)構(gòu)在查詢前必須知道該節(jié)點(diǎn)所處的層級(jí),否則無(wú)法確定自連接的深度。
鄰接表模型的局限性很大,用純SQL實(shí)現(xiàn)有一定的難度。不妨考慮其他模型,比如嵌套模型。
嵌套模型的基本結(jié)構(gòu)是樹(shù)型結(jié)構(gòu),SQL檢索比鄰接表要方便很多。
關(guān)于嵌套模型,PHPChina的第一期電子雜志PHPer也有過(guò)深入探討,請(qǐng)參考!
function get_category($id){
$str=array();
//$sql = "select * from biao where id=$id";查詢節(jié)點(diǎn),自己寫(xiě)吧
$result = array('id'=,'parent_id'=);//查詢結(jié)果一個(gè)數(shù)組格式
if($result){
$str = get_category($result['parent_id']);
$str[]=$result;
}
return $str;
}
}
調(diào)用get_category()就行了,$str第一個(gè)元素是節(jié)點(diǎn)本身,去掉就行了。
要構(gòu)建的無(wú)限分類(lèi)的模型. 電子產(chǎn)品是最大的分類(lèi).家用電器 ,數(shù)碼產(chǎn)品是其子分類(lèi).可以看到子分類(lèi)是被父分類(lèi)包含起來(lái)的.每個(gè)分類(lèi)都有左右 兩個(gè)節(jié)點(diǎn)編號(hào)分別是1、2、3.....
根據(jù)上面的圖mysql中建立表和插入數(shù)據(jù)
CREATE TABLE ?`product_categories` (
`id` MEDIUMINT( 8 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,`name` VARCHAR( 20 ) NOT NULL ,
`left_node` MEDIUMINT( 8 ) NOT NULL ,
`right_node` MEDIUMINT( 8 ) NOT NULL
) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci;INSERT INTO `product_categories` (`id`, `name`, `left_node`, `right_node`) VALUES(1, '電子產(chǎn)品', 1, 20),
(2, '家用電器', 2, 9),
(3, '電視機(jī)', 3, 4),
(4, '電冰箱', 5, 6),
(5, '空調(diào)', 7, 8),
(6, '數(shù)碼產(chǎn)品', 10, 19),
(7, '電腦', 11, 18),
(8, '臺(tái)式電腦', 12, 13),
(9, '筆記本電腦', 14, 15),
(10, '平板電腦', 16, 17);
表結(jié)構(gòu)如下:
下面是PHP的實(shí)例代碼:
1、獲取所有節(jié)點(diǎn)
?php
$pdo = new PDO(
'mysql:host=localhost;dbname=test',
'root',
''
);
$pdo-exec("SET NAMES UTF8");
$stmt = $pdo-prepare("SELECT c.name FROM product_categories as c, product_categories as pWHERE c.left_node BETWEEN p.left_node AND p.right_nodeAND p.name='電子產(chǎn)品' ORDER BY c.left_node");$stmt-execute();
$rs=$stmt-fetchAll(PDO::FETCH_ASSOC);
foreach($rs as $v){
echo $v['name'].'br /';
}
輸出:
電子產(chǎn)品
家用電器
電視機(jī)
電冰箱
空調(diào)
數(shù)碼產(chǎn)品
電腦
臺(tái)式電腦
筆記本電腦
平板電腦
2、 獲取某個(gè)父節(jié)點(diǎn)以及其所有子節(jié)點(diǎn)
?php
$pdo = new PDO(
'mysql:host=localhost;dbname=test',
'root',
''
);
$pdo-exec("SET NAMES UTF8");
$stmt = $pdo-prepare("SELECT c.name FROM product_categories as c, product_categories as pWHERE c.left_node BETWEEN p.left_node AND p.right_nodeAND p.name='數(shù)碼產(chǎn)品' ORDER BY c.left_node");$stmt-execute();
$rs=$stmt-fetchAll(PDO::FETCH_ASSOC);
foreach($rs as $v){
echo $v['name'].'br /';
}
輸出:
數(shù)碼產(chǎn)品
電腦
臺(tái)式電腦
筆記本電腦
平板電腦
3、獲取所有的葉子節(jié)點(diǎn)
?php
$pdo = new PDO(
'mysql:host=localhost;dbname=test',
'root',
''
);
$pdo-exec("SET NAMES UTF8");
$stmt = $pdo-prepare("SELECT name FROM product_categories where right_node-left_node=1");$stmt-execute();
$rs=$stmt-fetchAll(PDO::FETCH_ASSOC);
foreach($rs as $v){
echo $v['name'].'br /';
}
輸出:
電視機(jī)
電冰箱
空調(diào)
臺(tái)式電腦
筆記本電腦
平板電腦
4、獲取某個(gè)子節(jié)點(diǎn)及其所有父節(jié)點(diǎn)
?php
$pdo = new PDO(
'mysql:host=localhost;dbname=test',
'root',
''
);
$pdo-exec("SET NAMES UTF8");
$stmt = $pdo-prepare("SELECT p.name FROM product_categories AS c, product_categories AS p WHERE c.left_node BETWEEN p.left_node AND p.right_node AND c.name = '平板電腦' ORDER BY p.left_node");$stmt-execute();
$rs=$stmt-fetchAll(PDO::FETCH_ASSOC);
foreach($rs as $v){
echo $v['name'].'br /';
}
輸出:
電子產(chǎn)品
數(shù)碼產(chǎn)品
電腦
平板電腦
5、獲取所有節(jié)點(diǎn)極其所處的層級(jí)
?php
$pdo = new PDO(
'mysql:host=localhost;dbname=test',
'root',
''
);
$pdo-exec("SET NAMES UTF8");
$stmt = $pdo-prepare("SELECT c.name, (COUNT(p.name) - 1) AS level FROM product_categories AS c, product_categories AS p WHERE c.left_node BETWEEN p.left_node AND p.right_node GROUP BY c.name ORDER BY c.left_node");$stmt-execute();
$rs=$stmt-fetchAll(PDO::FETCH_ASSOC);
var_dump($rs);
echo 'br /';
foreach($rs as $v){
echo $v['name'].' level:'.$v['level'].'br /';}
輸出:
電子產(chǎn)品 level:0
家用電器 level:1
電視機(jī) level:2
電冰箱 level:2
空調(diào) level:2
數(shù)碼產(chǎn)品 level:2
電腦 level:2
臺(tái)式電腦 level:3
筆記本電腦 level:3
平板電腦 level:3
6、獲取某個(gè)節(jié)點(diǎn)的層級(jí)
?php
$pdo = new PDO(
'mysql:host=localhost;dbname=test',
'root',
''
);
$pdo-exec("SET NAMES UTF8");
$stmt = $pdo-prepare("SELECT c.name, (COUNT(p.name) - 1) AS level FROM product_categories AS c, product_categories AS p WHERE c.left_node BETWEEN p.left_node AND p.right_node and c.name='平板電腦' GROUP BY c.name ORDER BY c.left_node");$stmt-execute();
$rs=$stmt-fetchAll(PDO::FETCH_ASSOC);
var_dump($rs);
echo 'br /';
foreach($rs as $v){
echo $v['name'].' level:'.$v['level'].'br /';}
輸出:
平板電腦 level:3
7、在某個(gè)節(jié)點(diǎn)后平行的插入一個(gè)節(jié)點(diǎn)
?php
$pdo = new PDO(
'mysql:host=localhost;dbname=test',
'root',
''
);
$pdo-exec("SET NAMES UTF8");
function addNode($left_node,$new_node){
global $pdo;
$stmt = $pdo-prepare("SELECT right_node FROM product_categories WHERE name = '$left_node'");$stmt-execute();
$rs=$stmt-fetch(PDO::FETCH_ASSOC);
$right_node=$rs['right_node'];
$pdo-exec("UPDATE product_categories SET right_node = right_node + 2 WHERE right_node $right_node");$pdo-exec("UPDATE product_categories SET left_node = left_node + 2 WHERE left_node $right_node");$pdo-exec("INSERT INTO product_categories(name, left_node, right_node) VALUES('$new_node', $right_node + 1, $right_node + 2)");}
addNode('家用電器','辦公用品');
完成之后表結(jié)構(gòu)如下:
8、刪除某個(gè)節(jié)點(diǎn)及其所有子節(jié)點(diǎn)
?php
$pdo = new PDO(
'mysql:host=localhost;dbname=test',
'root',
''
);
$pdo-exec("SET NAMES UTF8");
function deleteNode($node_name){
global $pdo;
$stmt = $pdo-prepare("SELECT left_node,right_node, right_node - left_node + 1 as width FROM product_categories WHERE name ='$node_name'");$stmt-execute();
$rs=$stmt-fetch(PDO::FETCH_ASSOC);
$left_node=$rs['left_node'];
$right_node=$rs['right_node'];
$width=$rs['width'];
$pdo-exec("DELETE FROM product_categories WHERE left_node BETWEEN $left_node AND $right_node");$pdo-exec("UPDATE product_categories SET right_node = right_node - $width WHERE right_node $right_node");$pdo-exec("UPDATE product_categories SET left_node = left_node - $width WHERE left_node $right_node");}
deleteNode('數(shù)碼產(chǎn)品');
完成之后表結(jié)構(gòu)如下:
可以看到用多叉樹(shù)的方式構(gòu)建無(wú)限分類(lèi),查詢的時(shí)候是非常簡(jiǎn)便的.但是在插入新的節(jié)點(diǎn)和刪除節(jié)點(diǎn)時(shí)就比較麻煩了.
給你個(gè)原理吧
先找第一層
然后在里面遞歸獲取下一層的
如果你知道遞歸怎么寫(xiě)的應(yīng)該就明白了
分享名稱(chēng):php獲取數(shù)據(jù)的父節(jié)點(diǎn) php獲取flag
文章路徑:http://jinyejixie.com/article44/dosspee.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站、、App設(shè)計(jì)、用戶體驗(yàn)、小程序開(kāi)發(fā)、定制網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)