PHP實例:一無限分類的處理類_PHP教程
教程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) . ' -> ';
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(" ", floor * 3)
. '├'
. (ProcessFunc ? ProcessFunc(Data[i]) : Data[i]['CategoryName'])
. "</option>\n";
}
else
{
Str .= "<option value='{Data[i]['ID']}'>"
. str_repeat(" ", 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)點:避
相關(guān)PHP教程:
PHP教程Rss訂閱編程教程搜索
PHP教程推薦
- php小經(jīng)驗:解析preg_match與preg_match_all 函數(shù)
- 解決PHP mysql_query執(zhí)行超時(Fatal error: Maximum execution time …)
- 記錄mysql性能查詢過程的使用方法
- 解析php中rename()函數(shù)的妙用
- PHP中header和session_start前不能有輸出的原因
- 如何批量替換相對地址為絕對地址
- 獲取php頁面執(zhí)行時間,數(shù)據(jù)庫讀寫次數(shù),函數(shù)調(diào)用次數(shù)等(THINKphp)
- php分頁類
- PHP最常用的2種設(shè)計模式:工廠模式和單例模式
- 淺析PHP構(gòu)建語義Web CRUD操作
- 相關(guān)鏈接:
- 教程說明:
PHP教程-PHP實例:一無限分類的處理類。