PHP在無限分類時註意的一些問題(不保證代碼完全正確哦)

来源:https://www.cnblogs.com/Super-Lee/archive/2019/05/11/10847651.html
-Advertisement-
Play Games

轉自:PHP在無限分類時註意的一些問題(http://lxiaoke.cn) (註意:代碼使用的是原生PHP,旨在提供解決思路)1 無限分類的查找(獲取所有節點) 代碼: /** * 無限分類查詢,預設 pid 為 0 * @param $pid * @return array $res */ pr ...


轉自:PHP在無限分類時註意的一些問題(http://lxiaoke.cn) (註意:代碼使用的是原生PHP,旨在提供解決思路)
1 無限分類的查找(獲取所有節點)

代碼:

/**
 * 無限分類查詢,預設 pid 為 0
 * @param $pid
 * @return array $res
 */
protected function selectTree($pid = 0)
{
    $res = [];
    $sql = "SELECT * FROM " . $this->tbname . " WHERE pid=" . $pid;
    $result = @mysqli_query($this->link, $sql);
    if ($result) {
        $count = mysqli_num_rows($result);
        if ($count > 0) {
            while ($rows = mysqli_fetch_assoc($result)) {
                $rows['children'] = $this->selectTree($rows['id']);
                $res[] = $rows;
            }
        }
        mysqli_free_result($result);
    }
    return $res;
}

 

2 無限分類節點的刪除,不能單純地刪除當前節點,需要查找到當前節點下的所有子節點,一併刪除

代碼:

/**
 * 刪除目錄樹
 * @param $id
 */
protected function deleteTree($id)
{
    $res = $this->selectTree($id);
    if (!empty($res)) {
        foreach ($res as $v) {
            $this->deleteTree($v['id']);
        }
    }
    $sql = "DELETE FROM " . $this->tbname . " WHERE id=" . $id;
    mysqli_query($this->link, $sql);
}
3 **無限分類的編輯,由於在編輯的時候其父級是可選擇的,所以有可能造成用戶選擇到當前節點的子節點(),所以要進行判斷。雖說是無限分類,但正常情況下目錄深度是會有限度的,如果給定了目錄深度,還要判斷選擇父級之後的目錄深度是否超出範圍。

如果將編輯的元素放在其子元素下,所造成的問題:在查詢的時候無限迴圈!!

id

pid

name

1

0

test1

2

1

test2

修改之後:

id

pid

name

1

2

test1

2

1

test2

如上表所示,在進行無限分類查詢時,就會陷入死迴圈!

所以,針對可能會出現的問題,給出下麵的解決辦法,在用戶修改時進行判斷,通過則可以修改,未通過則給出提示。

3.1 判斷用戶選擇的是否是當前節點(這個只需要判斷選擇的節點和當前編輯節點的ID是否相同即可)

3.2 判斷用戶選擇的是否是子節點(如果是的話返回true   

 

/**
 * 判斷id所對應的元素是否是pid所對應元素的子元素,是的話返回true
 * @param $id
 * @param $pid
 * @return boolean $result
 */
protected function isChild($id, $pid)
{
    $result = false;
    $sql = "SELECT pid FROM " . $this->tbname . " WHERE id=" . $id;
    $res = @mysqli_query($this->link, $sql);
    if ($res) {
        while ($rows = mysqli_fetch_assoc($res)) {
            $result = ($pid === $rows['pid']) ? true : (($rows['pid'] !== 0) ? $this->isChild($rows['pid'], $pid) : false);
        }
    }
    return $result;
}

3.3 判斷用戶選擇的節點是否已經達到目錄深度

在做完後面的一步之後,這一步就比較好實現了:

/**
 * 判斷所選元素是否達到目錄深度,達到返回true
 * @param $id
 * @return mixed
 */
protected function isMaxDeep($id)
{
    return $this->deepUp($id) >= $this->maxDeep;
}

3.4 判斷修改之後的目錄深度是否超出限定範圍

 

/**
 * 修改之後的最終深度,如果深度大於規定深度,返回true
 * @param $pid
 * @param $id
 * @return mixed
 */
protected function lastDeep($pid, $id)
{
    return ($this->deepUp($pid) + $this->deepDown($id)) > $this->maxDeep;
}

/**
 * 向上查找父元素的深度
 * @param $id
 * @param int $k
 * @return int
 */
protected function deepUp($id, $k = 1)
{
    $sql = "SELECT pid FROM " . $this->tbname . "WHERE id=" . $id;
    $res = @mysqli_query($this->link, $sql);
    if ($res) {
        while ($rows = mysqli_fetch_assoc($res)) {
            ($rows['pid'] !== 0) && $k = $this->deepUp($rows['pid'], $k+1);
        }
    }
    return $k;
}

/**
 * 向下查找子元素的深度
 * @param $id
 * @param int $k
 * @return int
 */
protected function deepDown($id, $k = 0)
{
    $sql = "SELECT * FROM " . $this->tbname . "WHERE pid=" . $id;
    $res = @mysqli_query($this->link, $sql);
    if ($res && mysqli_num_rows($res) > 0) {
        $k++;
        while ($rows = mysqli_fetch_assoc($res)) {
            $k = max($k, $this->deepDown($rows['id'], $k))
        }
    }
    return $k;
}

經過上面的判斷之後,根據返回的結果就能判斷是否可以修改,如果返回true,則不可以修改,如果是false則可以進行修改。

(如果不用無限分類查詢,只是普通的查詢,讓前端去實現結果的顯示會怎麼樣呢??不懂那些框架是怎麼實現的,感覺也是在用遞歸)


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • [註]: popstate 事件 a.當活動歷史記錄條目更改時,將觸發popstate事件。 b.如果被激活的歷史記錄條目是通過對history.pushState()的調用創建的,或者受到對history.replaceState()的調用的影響,popstate事件的state屬性包含歷史條目的 ...
  • classdef SingletonClass < handle methods(Access = private) function obj = SingletonClass() disp('SingletonClass construtor called!'); end end methods(... ...
  • 電腦程式中涉及到的概念都比較抽象、專業。經常有初學者程式的人反應說,“別人說的什麼名詞性的東西,根本不明白是什麼意思”。的確,掌握一些開發相關的概念,與別人溝通起來非常的方便。對於初學者經常問的問題,做了個總結,希望給大家帶來幫助。 Q:經常聽到有人說,電腦語言可以歸為面向過程語言和麵向對象語言 ...
  • 常見的演算法設計策略 1.分治 分治法的設計思想是,將一個難以直接解決的大問題,分割成k個規模較小的子問題,這些子問題相互獨立,且與原問題相同,然後各個擊破,分而治之。 分治法常常與遞歸結合使用:通過反覆應用分治,可以使子問題與原問題類型一致而規模不斷縮小,最終使子問題縮小到很容易求出其解,由此自然導 ...
  • 一 對象的記憶體佈局: 在HotSpot虛擬機中,對象在記憶體中存儲的佈局可以分為3塊區域:對象頭(Header),實例數據(Instance Data)和對齊填充(Padding)。 HotSpot的對象頭包括兩部分信息,一部分存儲對象運轉時自身信息,例如hashCode,GC分代年齡,鎖狀態標誌,線 ...
  • info.m ff.m 測試代碼 ...
  • 緣起 本項目是基於之前學習的一個Dubbo+SSM分散式項目進行升級,基於此項目對前後端分離項目、微服務項目進一步深入學習。之前學習了vue、springBoot、springCloud後,沒有進行更多實戰練習,藉助此機會,整合之前所學知識,搭建一套微服務電商系統。本項目純屬個人學習總結,如有錯誤之 ...
  • 在c語言中實現全排列,對於剛接觸c語言,還沒學習演算法的人來說,比較困難了吧。估計大佬也不會看這種基礎的東西,全排列實現的辦法很多,在c++中有一個專門的函數可以使用,但是在c中實現就有點困難了。如果你想出用一個迴圈使一個數字每一位都不相同,那麼你就走進了死衚衕,這種辦法運算量巨大,往往到了高位就會超 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...