PHP實例:一無限分類的處理類_PHP教程

      編輯Tag賺U幣
      教程Tag:暫無Tag,歡迎添加,賺取U幣!

      推薦:PHP實例:PHP批量生成縮略圖
      到今天我學(xué)PHP已經(jīng)快一年了。不過小弟資質(zhì)相當(dāng)有限,一直沒有做出什么好東西來。在工作中有時需要把大批量的圖片變小,這是一件很簡單但很無聊的事情。有一天突發(fā)奇想,怎么不用PHP來做一個小程序呢?于是昨天完成了一個批量生成縮略圖的小程序,F(xiàn)在發(fā)布出

      PHP代碼:--------------------------------------------------------------------------------

      <?php
      /* 名稱: 對分類操作的業(yè)務(wù)邏輯封裝

      * 說明: 本類中引用的其它類(DB、Table、Item)均未提供,所以本類只能做個參考,不能直接應(yīng)用
      * 不是本人小氣不提供其它類,實在是因為那些都是一兩年前寫的類,很爛。怕大家看后對大
      * 造成誤導(dǎo). 在此發(fā)表這個類,只希望大家能從中學(xué)到一些程序設(shè)計的方法。

      * 特點:
      * 采用遞歸調(diào)用的方法,對分類數(shù)據(jù)只需一次數(shù)據(jù)庫查詢可生成樹狀結(jié)構(gòu)。 無限遞歸層次(視機器堆棧而定)
      *
      * 數(shù)據(jù)庫定義:
      * ID smallint unsigned primary #如果數(shù)據(jù)量很大可用int
      * ParentID smallint unsigned index #如果數(shù)據(jù)量很大可用int, 請索引此字段
      * #如果為根分類,則ParentID = 0
      *
      * RootID smallint unsigned index #如果數(shù)據(jù)量很大可用int, 請索引此字段
      * #如果是根分類則RootID = 0, 否則RootID = 最上層的父分類ID
      * CategoryName varchar(n) #此大小自定
      * 如需有其它字段定義附在后面

      * 注意事項:
      * 不要試圖直接調(diào)用本類,除非你有和我定義那另外那幾個類相對應(yīng)的接口, 否則不會成功
      * 在合適的地方定義 DBTABLE_CATEGORY 這個常量 190-711 190-721 ,使其指向你的分類數(shù)據(jù)表名字
      *
      * 程序構(gòu)架:
      * ├─基礎(chǔ)類 <!-- 完成底層數(shù)據(jù)庫操作、數(shù)據(jù)抽象、語言、模板、異常、雜項等)操作 -->
      * │
      * │
      * └─業(yè)務(wù)邏輯層(此類所處層次) <!-- 利用基礎(chǔ)類中數(shù)據(jù)操作、數(shù)據(jù)抽象等類根據(jù)表現(xiàn)層傳遞的參數(shù)完成數(shù)據(jù)處理,并返回數(shù)據(jù)或操作結(jié)果 -->
      * │
      * │
      * └───表現(xiàn)層(用戶界面) <!-- 利用業(yè)務(wù)邏輯層將取得的數(shù)據(jù)或操作數(shù)據(jù)的結(jié)果通過基礎(chǔ)類中的界面等類進行顯示 -->
      */

      define('DBTABLE_CATEGORY', 'xxx');

      class Category_Logic
      {
      var KernelRef = NULL; //系統(tǒng)核心的引用
      var tblObj = NULL; //包含當(dāng)前分類數(shù)據(jù) Table 類的實例

      var _CurrentItem = NULL; //包含當(dāng)前分類數(shù)據(jù) TItem類的實例

      var CategoryID = 0; //當(dāng)前分類ID,如果沒有當(dāng)前分類此項為 0

      //---------------------------------------------------------------------------
      //private array GetNodeData(array Data, int ParentNode)
      // 根據(jù)一顆指定根的并且以兄弟雙親法表示的樹和當(dāng)前分類的ID,返回當(dāng)前分類在整個分類表中所處的位置
      //
      // @param: Data 2維數(shù)組 Array(
      // Array(
      // 'ID' => 分類ID,
      // 'ParentID' => 父分類ID,
      // 'RootID' => 根分類ID,
      // 'CategoryName' => 分類名稱,
      // ),
      // ……
      // );
      // 表示的一顆樹
      //
      // @param: ParentNode 父分類ID, 每一次由調(diào)用者給出,遞歸時由程序計算傳遞
      //
      // return value: 返回以兄弟雙親法表示的所有分類的樹
      // 注意: 確保當(dāng)前分類已經(jīng)設(shè)置,否則此函數(shù)無返回
      //
      //---------------------------------------------------------------------------
      function GetNodeData(Data, ParentNode)
      {
      arr = Array();

      ArrayCount = 0;

      for(i = 0, cnt = Count(Data); i < cnt; i++)
      {
      if(Data[i]['ParentID'] == ParentNode)
      {
      arr[ArrayCount] = Data[i];
      arr[ArrayCount++]['Child'] = this->GetNodeData(Data, Data[i]['ID']);
      }
      }

      return arr;
      }

      //---------------------------------------------------------------------------
      //private String _CurrentLevel(array Data, int Current, String ProcessFunc = '')
      // 根據(jù)一顆指定根的并且以兄弟雙親法表示的樹和當(dāng)前分類的ID,返回當(dāng)前分類在整個分類表中所處的位置
      //
      // @param: Data 兄弟雙親法表示的樹, 由調(diào)用者傳遞
      //
      // @param: Current 當(dāng)前分類ID,第一次調(diào)用時由調(diào)用者給出,遞歸時由程序自行計算
      //
      // @param: ProcessFunc 指定對分類數(shù)據(jù)的處理函數(shù), 函數(shù)原型定義見 this->PrintCurrentLevel 中的注釋
      //
      // return value: 返回當(dāng)前分類在分類樹中的位置
      // 注意: 確保當(dāng)前分類已經(jīng)設(shè)置,否則此函數(shù)無返回
      //
      //---------------------------------------------------------------------------
      function _CurrentLevel(Data, Current, ProcessFunc = '')
      {
      for(i = 0; i < Count(Data); i++)
      {
      if(Data[i]['ID'] == Current)
      {
      if(Data[i]['ParentID'] != 0)
      {
      str = this->_CurrentLevel(Data, Data[i]['ParentID'], ProcessFunc) . ' -&gt; ';

      if(ProcessFunc) str .= ProcessFunc(Data[i]);
      else str .= Data[i]['CategoryName'];
      }
      else
      {
      if(ProcessFunc) str = ProcessFunc(Data[i]);
      else str = Data[i]['CategoryName'];
      }
      break;
      }
      }

      return str;
      }

      //---------------------------------------------------------------------------
      //public Category_Logic(Object &Kernel, int CategoryID = -1)
      // 本類構(gòu)造函數(shù)
      //
      // @param: Kernel 此參數(shù)為當(dāng)前系統(tǒng)核心類的一個引用, 核心類中包括
      // 數(shù)據(jù)庫類、輸入輸出類、系統(tǒng)配置類等
      //
      // @param: CategoryID 當(dāng)前分類ID。
      // 當(dāng)想調(diào)用 PrintCurrentLevel、GetRootID、GetParentID、GenerateTypeTreeList及
      // 調(diào)用_CurrentItem成員的方法時請先設(shè)置此值.
      //
      // 調(diào)用GenerateTypeTreeList時設(shè)置此值,則沒有ID為此的分類默認被選擇,沒設(shè)置則無默認
      //
      // return value: none
      //
      //---------------------------------------------------------------------------
      function &Category_Logic(&Kernel, CategoryID = -1)
      {
      this->KernelRef = &Kernel;

      this->tblObj = new Table(Kernel->DBObj, DBTABLE_CATEGORY);

      if(CategoryID != -1)
      {
      this->SetCategoryID(CategoryID);
      }
      }

      //---------------------------------------------------------------------------
      //public void SetCategoryID(int CategoryID)
      // 設(shè)置當(dāng)前分類ID
      //
      // return value: none
      //
      //---------------------------------------------------------------------------
      function SetCategoryID(CategoryID)
      {
      if(!CategoryID) return;

      Item = new TItem(this->KernelRef->DBObj, DBTABLE_CATEGORY, '*', CategoryID ,'ID');

      this->_SelfData = &Item;

      this->CategoryID = CategoryID;
      }

      //---------------------------------------------------------------------------
      //public int GetRootID()
      // 返回當(dāng)前分類的根分類ID
      // 注意:只有設(shè)置的當(dāng)前分類時此函數(shù)才有效
      //
      // return value: 返回當(dāng)前分類的根分類ID
      //
      //---------------------------------------------------------------------------
      function GetRootID()
      {
      return this->_SelfData->Get('RootID');
      }

      //---------------------------------------------------------------------------
      //public int GetParentID()
      // 返回當(dāng)前分類的父分類ID
      // 注意:只有設(shè)置的當(dāng)前分類時此函數(shù)才有效
      //
      // return value: 返回當(dāng)前分類的父分類ID
      //
      //---------------------------------------------------------------------------
      function GetParentID()
      {
      if(this->CategoryID) return this->_SelfData->Get('ParentID');
      }


      //---------------------------------------------------------------------------
      //public String GenerateTypeTreeList(array Data, String ProcessFunc, int floor = 0)
      // 返回整個分類的樹狀結(jié)構(gòu)放在OptionList中的列表
      //
      // @param: Data 此參數(shù)由 this->DumpTypeDataToTree() 返回
      //
      // @param: ProcessFunc 處理顯示分類信息的回調(diào)函數(shù), 函數(shù)原型請參照: this->PrintCurrentLevel()
      //
      // @param: floor 本參數(shù)不能人為給出,是程序自動計算的中間值
      //
      // return value:
      // 結(jié)構(gòu)為一顆兄弟雙親表示法表示的樹
      // 設(shè)如分類數(shù)據(jù)如下:
      // ├──1級分類
      // │
      // │
      // │
      // ├─2級分類
      // │ │
      // │ └─3級分類
      // │
      // └─2級分類
      //
      // 則返回值為 Array(
      // 0 => Array(
      // 'ID' => '',
      // 'ParentID' => '',
      // 'RootID' => '',
      // 'CategoryName' => '',
      // 'Child' => ....
      // )
      // .....
      // )
      //
      //---------------------------------------------------------------------------
      function DumpTypeDataToTree(RootID = 0, Fields = '*')
      {
      this->tblObj->SetFields(Fields);
      this->tblObj->SetCondition('');

      List = this->tblObj->MapResult(this->tblObj->Select());

      return this->GetNodeData(List, RootID);
      }

      //---------------------------------------------------------------------------
      //public String GenerateTypeTreeList(array Data, String ProcessFunc = '', int floor = 0)
      // 返回整個分類的樹狀結(jié)構(gòu)放在OptionList中的列表
      //
      // @param: Data 此參數(shù)由 this->DumpTypeDataToTree() 返回
      //
      // @param: ProcessFunc 處理顯示分類信息的回調(diào)函數(shù), 函數(shù)原型請參照: this->PrintCurrentLevel()
      //
      // @param: floor 本參數(shù)不能人為給出,是程序自動計算的中間值
      //
      // return value: 返回一個<option>分類名稱1</option> ... <option>分類名稱n</option>
      //
      // ps: 調(diào)用時echo "<select name='xxxx'>" . _c->GenerateTypeTreeList(Data, 'ProcessFunc') . "</select>";
      //
      //---------------------------------------------------------------------------
      function GenerateTypeTreeList(Data, ProcessFunc, floor = 0)
      {
      Str = '';
      for(i = 0, cnt = Count(Data); i < cnt; i++)
      {
      if(this->CategoryID == Data[i]['ID'])
      {
      Str .= "<option value='{Data[i]['ID']}' selected>"
      . str_repeat("&nbsp;", floor * 3)
      . '├'
      . (ProcessFunc ? ProcessFunc(Data[i]) : Data[i]['CategoryName'])
      . "</option>\n";
      }
      else
      {
      Str .= "<option value='{Data[i]['ID']}'>"
      . str_repeat("&nbsp;", floor * 3)
      . '├'
      . (ProcessFunc ? ProcessFunc(Data[i]) : Data[i]['CategoryName'])
      . "</option>\n";
      }

      if(Data[i]['Child']) Str .= this->GenerateTypeTreeList(Data[i]['Child'], ProcessFunc, floor + 1);
      }

      return Str;
      }

      //---------------------------------------------------------------------------
      //public String GenerateTypeTreeView(array Data, String ProcessFunc = '')
      // 返回整個分類的樹狀結(jié)構(gòu)視圖
      //
      // @param: Data 此參數(shù)由 this->DumpTypeDataToTree() 返回
      //
      // @param: ProcessFunc 處理顯示分類信息的回調(diào)函數(shù), 函數(shù)原型請參照: this->PrintCurrentLevel()
      //
      // return value: 返回生成的一顆HTML形式顯示的樹
      //
      //---------------------------------------------------------------------------
      function GenerateTypeTreeView(Data, ProcessFunc)
      {
      Str = '<ul style="Line-Height:200%">';

      for(i = 0, cnt = Count(Data); i < cnt; i++)
      {
      if(ProcessFunc) Str .= '<li>' . ProcessFunc(Data[i]) . '</li>' . "\n";
      else Str .= '<li>' . Data[i]['CategoryName'] . '</li>' . "\n";

      if(Data[i]['Child']) Str .= '<li>' . this->GenerateTypeTreeView(Data[i]['Child'], ProcessFunc) . '</li>';
      }

      Str .= '</ul>';

      return Str;
      }

      //---------------------------------------------------------------------------
      //public String PrintCurrentLevel(String ProcessFunc = '')
      // 對多級分類生成當(dāng)前位置字符串
      // 設(shè)如分類數(shù)據(jù)如下,當(dāng)前分類為3級分類, 則調(diào)用返回 1級分類 -> 2級分類 -> 3級分類
      // ├──1級分類
      // │
      // │
      // │
      // ├─2級分類
      // │ │
      // │ └─3級分類
      // │
      // └─2級分類
      //
      //
      //
      //
      // @param: ProcessFunc 此為對分類數(shù)據(jù)如何顯示的回調(diào)函數(shù),不設(shè)置則直接顯示分類名稱
      // 函數(shù)定義原型為 function (&arr);
      // 其中arr參數(shù)為每一個分類信息的一維數(shù)組如下:
      // array(ID => 1, ParentID => 0, RootID => 0, CategoryName => '1級分類')
      // 返回值為對上述數(shù)據(jù)處理的結(jié)果,比如返回帶鏈接的分類名字、更改顯示顏色等
      //
      // return value: 返回當(dāng)前分類在整個分類樹中所處位置
      //
      //---------------------------------------------------------------------------
      function PrintCurrentLevel(ProcessFunc = '')
      {
      if(!this->CategoryID) return '';

      if(this->_SelfData->Get("RootID") == 0)
      {
      if(ProcessFunc) return ProcessFunc(this->_SelfData->fetchDataToArray());
      else return this->_SelfData->Get("CategoryName");
      }

      Current = this->CategoryID;

      this->tblObj->SetCondition('RootID = ' . this->_SelfData->Get('RootID') . " or ID = " . this->_SelfData->Get('RootID'));

      Data = this->tblObj->MapResult(this->tblObj->Select());

      return this->_CurrentLevel(Data, Current, ProcessFunc);
      }

      //---------------------------------------------------------------------------
      //public boolean Add(array arr)
      // 添加新分類到分類表中
      //
      // @param: arr 在此數(shù)組中包括對新添加分類的定義, 定義如下:
      //
      // arr['RootID'] 新分類所屬的根分類ID
      // arr['ParentID'] 新分類的父分類ID
      // arr['CategoryName'] 新分類的名稱
      //
      // return value: 返回添加分類操作結(jié)果
      //
      //---------------------------------------------------------------------------
      function Add(arr)
      {
      this->tblObj->SetFields(
      Array(
      'RootID',
      'ParentID',
      'CategoryName',
      )
      );

      return this->tblObj->Insert(
      Array(
      arr['RootID'],
      arr['ParentID'],
      arr['CategoryName'],
      )
      );
      }

      //---------------------------------------------------------------------------
      //public boolean Delete(int ID)
      // 刪除已經(jīng)存在的分類
      //
      // @param: ID 要刪除的分類ID
      //
      // return value: 返回刪除分類操作結(jié)果
      //
      //---------------------------------------------------------------------------
      function Delete(ID)
      {
      sysOption = &this->KernelRef->Config;

      this->tblObj->SetFields('*');
      this->tblObj->SetCondition('ID = ' . (int)ID);

      return this->tblObj->Delete();
      }

      //---------------------------------------------------------------------------
      //public boolean Modify(int ID, array arr)
      // 修改已經(jīng)存在的分類
      //
      // @param: ID 要修改的分類ID
      // @param: arr 在此數(shù)組中包括修改后的分類定義, 定義如下:
      //
      // arr['RootID'] 新分類所屬的根分類ID
      // arr['ParentID'] 新分類的父分類ID
      // arr['CategoryName'] 新分類的名稱
      //
      // return value: 返回修改分類操作結(jié)果
      //
      //---------------------------------------------------------------------------
      function Modify(ID, arr)
      {
      this->tblObj->SetCondition('ID = ' . (int)ID);

      prev = this->tblObj->MapOneRow(this->tblObj->Select());

      this->tblObj->SetFields(
      Array(
      'RootID',
      'ParentID',
      'CategoryName',
      )
      );

      return this->tblObj->Update(arr);
      }

      //---------------------------------------------------------------------------
      //public array Modify(int ID)
      // 修改已經(jīng)存在的分類
      //
      // @param: ID 指定的分類ID
      //
      // return value: 返回指定ID分類的信息
      // 數(shù)組中包括:
      // Array(
      // 'ID' => 分類ID,
      // 'ParentID' => 父分類ID,
      // 'RootID' => 根分類ID,
      // 'CategoryName' => 分類名稱,
      // );
      //
      //---------------------------------------------------------------------------
      function GetCategory(ID)
      {
      this->tblObj->SetCondition('ID = ' . (int)ID);

      return this->tblObj->MapOneRow(this->tblObj->Select());
      }
      }
      ?>
       

      分享:如何避免頁面刷新數(shù)據(jù)重復(fù)寫入數(shù)據(jù)庫
      何避免頁面刷新數(shù)據(jù)重復(fù)寫入數(shù)據(jù)庫 當(dāng)表單的數(shù)據(jù)是提交給本頁面處理并寫入數(shù)據(jù)庫時,點提交后,刷新頁面的話使數(shù)據(jù)重復(fù)寫入數(shù)據(jù)庫。網(wǎng)上搜索一下,發(fā)現(xiàn)了不少的解決方案: 一、把一頁面分開為兩個,數(shù)據(jù)提交給另一個頁面處理,之后再跳到輸入頁面。 優(yōu)點:避

      來源:模板無憂//所屬分類:PHP教程/更新時間:2010-04-13
      相關(guān)PHP教程