ホームページ php教程 php手册 二款php无限分类代码与原理

二款php无限分类代码与原理

May 25, 2016 pm 04:56 PM
explode select

这种亲缘分类越多,程序和数据库的控制就越加的复杂困难.在同一级的分类处理和控制是非常的简单的,因为只需要一个数据库来记载这一级的分类就行了,如:系统,新闻等分类,在这一级上处理是很简单的,但对一个网站来说一级分类是不够的,还需要再分类

第一分类(父分类)-->第二分类(子分类)-->第三分类(孙分类)

这种亲缘分类越多,程序和数据库教程的控制就越加的复杂困难.在同一级的分类处理和控制是非常的简单的,因为只需要一个数据库来记载这一级的分类就行了,如:系统,新闻等分类,在这一级上处理是很简单的,但对一个网站来说一级分类是不够的,还需要再分类
//我们建一个表"class"
CREATE TABLE `class` (
  `id` int(11) NOT NULL auto_increment COMMENT '分类id',
  `f_id` int(11) NOT NULL COMMENT '父id',
  `name` varchar(25) collate gbk_bin NOT NULL COMMENT '分类名称',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=gbk COLLATE=gbk_bin AUTO_INCREMENT=1 ;
 
//首先我们往数据库里插入‘新闻’这个大分类,因为‘新闻’是最大分类,上面没有父类了,所以我把它的f_id设置为0。
INSERT INTO `class` (`id`, `f_id`, `name`) VALUES(1, 0, '新闻');   //id这个字段是自动增长的,可以不写值。
 
//然后我们再往数据库里插入‘PHP新闻’这个分类,它的父类‘新闻’的id是1,所以它的f_id设置为1。
INSERT INTO `class` (`id`, `f_id`, `name`) VALUES(2, 1, 'PHP新闻');
 
//然后我们再往数据库里插入‘PHP6.0出来了’这个分类,它的父类‘PHP新闻’的id是2,所以它的f_id设置为2。
INSERT INTO `class` (`id`, `f_id`, `name`) VALUES(3, 2, 'PHP6.0出来了');
 
//同理,我们可以这样一直往下插入分类,也就达到了无限分类。
//我们可以发现插入一个分类的原则关键是找到这个分类的父类的id,然后作为这个分类的f_id字段的值。
//假设要插入跟‘新闻’同一个级别的分类‘技术’,也就是说它也是最大分类,上面没有父类了,那么它的f_id也设置为0;
INSERT INTO `class` (`id`, `f_id`, `name`) VALUES(4, 0, '技术');
 
//在‘技术’下面又有一个分类‘PHP技术’,那么我们怎么插入呢,首先找到‘PHP技术’的父类‘技术’的id,然后作为自己的f_id字段的值。
INSERT INTO `class` (`id`, `f_id`, `name`) VALUES(5, 4, 'PHP技术');
 
//看到这里,想必大家应该都明白怎么往数据库里插入各个分类了。就不再举例了。

我们已经知道如何往数据库里插入各个分类了,那又如何把各个分类罗列出来呢?

header("Content-type:text/html;charset=utf-8");
$db=new mysql教程i("localhost","root","","news_php100") ; //实例化一个数据库连接。使用这个前一定要确保已经加载了mysqli类库,或者用mysql_connect这个方式连接。
if(mysqli_connect_errno()){
  echo "链接失败:".mysqli_connect_error();
  exit(); }
$db->query("set names utf8");
$result=$db->query("select name from class where f_id=0"); //查找f_id=0的分类,也就是查找每一个大类。
while($row=$result->fetch_assoc()){
      echo $row['name']."
";        //这样就把每个大类循环出来了。
}
//同样我们可以把新闻的子类循环出来。
$result=$db->query("select * from class where f_id=1"); //查找f_id=1的分类,也就是查找‘新闻’的子类。
while($row=$result->fetch_assoc()){
      echo $row['name']."
";        //这样就把‘新闻’的子类循环出来了。注意:只是子类,不包括孙子类。
}
//写到这里,我们会发现一个问题,如果这个分类是10级分类,难道我们要写10个循环把它每个子类循环出来?如果是更多级分类呢,这样写显然是不现实的。
//那又有什么办法解决呢?我们可以写一个递归的函数,把f_id作为参数传入,不断循环每一个f_id的值,也就是说把每一个f_id值的子类循环出来。
//首先我们把各个分类的值保存在一个二维数组中,在下面的递归函数里有用。
$result=$db->query("select * from class");
while($row=$result->fetch_assoc()){
     $arr[]=array($row[id],$row[f_id],$row[name]);    //每一行保存一个分类的id,f_id,name的信息。
}
function fenlei($f_id=0){     //$f_id初始化为0,也就是从最大分类开始循环.
    global $arr;   //声明$arr为全局变量才可在函数里引用。
    for($i=0;$i           if($arr[$i][1]==$f_id){         //$arr[$i][1]表示第$i+1个分类的f_id的值。开始$f_id=0,也就是把f_id=0的分类输出来。
                 echo $arr[$i][2]."
"; //$arr[$i][1]表示第$i+1个分类的name的值。
            fenlei($arr[$i][0]);   //$arr[$i][1]表示第$i+1个分类的id的值。进行递归,也就是把自己的id作为f_id参数把自己的子类再循环出来。
}
}
}
?>


在介绍这个功能前,先介绍一下 explode( ) 这个函数,这是个字串处理函数,用来分解字串的,具体的用法,例:

分解"0:1:2:3:4"里的数字

$val="0:1:2:3:4";
$rid=explode(":",$val);

经过 explode( ) 函数处理,$val 内的所有数字都分解到 $rid 数组中了,要引用时只需打印:echo "$rid[0],$rid[1],$rid[2]..."; 就行了.explode( ) 函数在整个分类处理中起着非常重要的作用,好现在开始介绍无现分类的程序控制.

可以假设个总分类 0 ,所有的分类都是它的子孙分类,现在来建立第一个分类"系统",来看看它在数据库的存储形式:

id | uid | type | rout_id | rout_char
1 | 0 | 系统 | 0:1 | 系统

接着又在下面分"Linux":

id | uid | type | rout_id | rout_char
2 | 1 | Linux| 0:1:2 | 系统:Linux

以上就是数据库存储的形式,现在就来完成 php 的代码,这与论坛的代码很相似,我们所要做的就是将分类的 id 放入 uid,而父分类的 uid 就放 0,下面来看看代码:


.....
.....

//设置默认页
if (empty($func)) $func=="showtype";

//设置父分类的 uid
if (empty($uid)) $uid=0;

//数据库存储************************************************
if ($func=="save"):

$fields = "";
$values = "";

if ($id!="") {
$fields .= ",id";
$values.=",$id";
}

if ($uid!="") {
$fields .= ",uid";
$values.=",$uid";
}

if ($type!="") {
$fields .= ",type";
$values.=","$type"";
}

if ($route_id=="") {

//取得父分类的 route_id
if ($uid!=0) {
$result = mysqlquery("select * from type where id=$uid");
$route_id=mysql_result($result,0,"route_id");
} else {
$routr_id="0";
}
$fields .= ",route_id";
//形成自己的 route_id
$route_id="$route_id:$id";
$values.=","$route_id"";
}

//形成自己的 route_char
if ($route_char!="") {
$fields .= ",route_char";
$route_char="$route_char:$type";
$values.=","$route_char"";
} else {
$fields .= ",route_char";
$route_char=$type;
$values.=","$route_char"";
}

$fields = substr($fields,1,strlen($fields)-1);
$values = substr($values,1,strlen($values)-1);

$result = mysqlquery("insert into type ($fields) values ($values)");
...
endif; /* end save */


//分类上传************************************************
if ($func=="createtype"):

//取得自己的 id
$result = mysqlquery("select * from type order by
id desc");
$num=mysql_numrows($result);
if (!empty($num)) {
$cat = mysql_result($result,0,"id");
} else {
$cat=0;
}

//判断分类的状态
if ($uid != 0) {
$result=mysql_query("select * from type where id=$uid");
$type=mysql_result($result,0,"type");
$route_char=mysql_result($result,0,"route_char");
} else {
$type="父分类";
}
echo "

";

echo "

";
echo "";
echo "";

echo "

";

echo "

所属类别:$type
创建分类:
";
$cat=$cat+1;
echo "";
echo "";
echo "";
echo "
";
echo "
";
endif; /* end createtype */

//显示分类************************************************
if ($func=="showtype"):

echo "

";

//判断分类的状态
if ($uid!=0) {
$result=mysql_query("select * from type where id=$uid");
$type=mysql_result($result,0,"type");
} else {
$type="父分类";
}

echo "

";

echo "

";

$result=mysql_query("select * from type where uid=$uid");
$num=mysql_numrows($result);

if (!empty($num)) {
for ($i=0;$i

$id=mysql_result($result,$i,"id");
$type=mysql_result($result,$i,"type");

echo "

";
}
}

echo "

创建分类
$type
";
echo "$type";
echo "
";
endif; /* end showtype */
.....
.....

?>

以上的程序便完成了无限分类的基本创建,存储和显示,接着就是完善分类创建功能的各个部分了.
4.路径跟踪
------------------------------------------------------------
前面已经介绍过了分类的创建实现方法,在分类表里记载了 rout_id 和 rout_char 这两个存储分类路径的信息,在不做任何处理的情况下,程序只能够顺序下到最底层的分类而无法倒退(当然可利用浏览器的 back 键倒退,但这对程序来说是不完整的),因此必须将 rout_id 和 rout_char 的信息分解出来完成实在的路径指示.

具体的做法,假如数据库记载了这么一条分类信息:

id:4
uid:2
type:开发工具
rout_id:0:1:2:4
rout_char:系统:linux:开发工具

当程序走到分类'开发工具'上时,除了要求显示路径信息外还要求能够去到路径上的任一分类中,该怎么做能?这里就需要用到 explode() 函数了.因为 rout_id 和 rout_char 是对应关系的,所以可将它们分解:

$path=explode(":",$rout_id);
$path_gb=explode(":",$rout_char);

这时所有分类信息都被分解了,现在要做的就是以链接的方式还原路径信息:
[php]
for ($i=0;;$i++) {
$a=$i+1;
echo "href=$php_self?func=showtype&uid=",$path[$a],">",$path_gb[$i],":";
if (empty($path_gb[$i])) {
break;
}
}
[/php]
上面这段代码就实现了加链接还原路径的功能,因为实现的是无限分类,因此是没有上限的,所以在 for($i=0;;$i++) 里没有范围限制,而设置循环退出的条件是 $path_gb[$i] 中的值为空,将这段代码插入类别显示版面的程序块内就行了:
[php]

.....
.....
//显示分类************************************************
if ($func=='showtype'):

echo "

";

//判断分类的状态
if ($uid!=0) {
$result=mysql_query("select * from type where id=$uid");
$type=mysql_result($result,0,"type");

//******** 新加入的代码 ***************
$rout_id=mysql_result($result,0,"rout_id");
$rout_char=mysql_result($result,0,"rout_char");
$path=explode(":",$rout_id);
$path_gb=explode(":",$rout_char);
echo "

";
//******** end ***********************

} else {
$type='父分类';
}

echo "

";

echo "

";

$result=mysql_query("select * from type where uid=$uid");
$num=mysql_numrows($result);

if (!empty($num)) {
for ($i=0;$i

$id=mysql_result($result,$i,"id");
$type=mysql_result($result,$i,"type");

echo "

";
}
}

echo "

";
for ($i=0;;$i++) {
$a=$i+1;
echo "href=$php_self?func=showtype&uid=",$path[$a],">",$path_gb[$i],":";
if (empty($path_gb[$i])) {
break;
}
}
echo "
创建分类
$type
";
echo "$type";
echo "
";
endif; /* end showtype */
.....
.....
?>
[/php]
完成这个功能块后,就可继续分类信息的显示实现了

教程地址:

欢迎转载!但请带上文章地址^^

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Select Channels Goの非同期処理方法 golangを使った並行プログラミング Select Channels Goの非同期処理方法 golangを使った並行プログラミング Sep 28, 2023 pm 05:27 PM

golang を使用した SelectChannelsGo 同時プログラミングの非同期処理方法 はじめに: 同時プログラミングは、アプリケーションのパフォーマンスと応答性を効果的に向上させることができる、現代のソフトウェア開発における重要な領域です。 Go 言語では、Channel と Select ステートメントを使用して同時プログラミングを簡単かつ効率的に実装できます。この記事では、SelectChannelsGo 同時プログラミングの非同期処理メソッドに golang を使用する方法を紹介し、具体的な方法を提供します。

jqueryでselect要素を非表示にする方法 jqueryでselect要素を非表示にする方法 Aug 15, 2023 pm 01:56 PM

jquery で select 要素を非表示にする方法: 1. hide() メソッド。jQuery ライブラリを HTML ページに導入します。さまざまなセレクターを使用して select 要素を非表示にできます。ID セレクターは、selectId を選択した select 要素の ID に置き換えます。実際に使用する; 2. css() メソッド、ID セレクターを使用して非表示にする必要がある select 要素を選択し、css() メソッドを使用して表示属性を none に設定し、selectId を select 要素の ID に置き換えます。

PHPのexplode関数の使い方とエラー解決方法 PHPのexplode関数の使い方とエラー解決方法 Mar 10, 2024 am 09:18 AM

PHP のexplode関数は、文字列を配列に分割するために使用される関数で、非常に一般的で柔軟性があります。分解関数を使用する過程で、エラーや問題が発生することがよくありますが、この記事では、分解関数の基本的な使用方法を紹介し、エラー報告を解決するいくつかの方法を紹介します。 1.explode関数の基本的な使い方 PHPでは、explode関数の基本的な構文は次のとおりです。explode(string$separator,string$stri

jQueryで選択要素の変更イベントバインディングを実装する方法 jQueryで選択要素の変更イベントバインディングを実装する方法 Feb 23, 2024 pm 01:12 PM

jQuery は、DOM 操作、イベント処理、アニメーション効果などを簡素化するために使用できる人気のある JavaScript ライブラリです。 Web 開発では、選択した要素のイベント バインディングを変更する必要がある状況によく遭遇します。この記事では、jQuery を使用して選択要素変更イベントをバインドする方法を紹介し、具体的なコード例を示します。まず、ラベルを使用してオプションを含むドロップダウン メニューを作成する必要があります。

PHP で展開関数を使用する場合の一般的なエラーと解決策 PHP で展開関数を使用する場合の一般的なエラーと解決策 Mar 11, 2024 am 08:33 AM

タイトル: PHP でexplode関数を使用する際の一般的なエラーと解決策 PHPでは、explode関数は、文字列を配列に分割するために使用される一般的な関数です。ただし、不適切な使用や不正なデータ形式が原因で、いくつかの一般的なエラーが発生する可能性があります。この記事では、explode 関数の使用時に発生する可能性のある問題を分析し、解決策と具体的なコード例を示します。間違い 1: delimiter パラメーターが渡されない。explode 関数を使用するときに最もよくある間違いの 1 つは、delimiter パラメーターが渡されないことです。

Linux が select を使用する理由は何ですか? Linux が select を使用する理由は何ですか? May 19, 2023 pm 03:07 PM

select を使用すると、開発者は複数のファイル バッファーを同時に待機できるため、IO 待機時間を短縮し、プロセスの IO 効率を向上させることができます。 select() 関数は、プログラムが複数のファイル記述子を監視し、監視されている 1 つ以上のファイル記述子が「準備完了」になるのを待機できるようにする IO 多重化関数です。いわゆる「準備完了」状態とは、ファイルを指します。記述子はブロックされなくなり、読み取り可能、書き込み可能、​​例外を含む特定の種類の IO 操作に使用できるようになりました。 select は、ヘッダー ファイル #include にあるコンピューター関数です。この関数は、ファイル記述子の変更 (読み取り、書き込み、または例外) を監視するために使用されます。 1. セレクト機能の概要 セレクト機能はIO多重化機能です。

explode関数とimplode関数を使用して文字列を分割および結合する explode関数とimplode関数を使用して文字列を分割および結合する Jun 15, 2023 pm 08:42 PM

PHP プログラミングでは、文字列の処理は頻繁に必要な操作です。その中で、文字列の分割と結合は 2 つの一般的な要件です。これらの操作をより便利に実行するために、PHP は 2 つの非常に実用的な関数、つまり、explode 関数と implode 関数を提供します。この記事では、これら2つの機能の使い方と実践スキルを紹介します。 1.explode関数explode関数は、指定された区切り文字に従って文字列を分割し、配列を返すために使用されます。その関数プロトタイプは次のとおりです。

mysqlのselect構文の使い方 mysqlのselect構文の使い方 Jun 01, 2023 pm 07:37 PM

1. SQL ステートメント内のキーワードは大文字と小文字を区別せず、SELECT は SELECT と同等、FROM は from と同等です。 2. users テーブルからすべての列を選択するには、記号 * を使用して列名を置き換えます。構文 -- これはコメントです -- FEOM で指定された [テーブル] から [すべての] データをクエリします * は [すべての列] を意味します SELECT*FROM -- 指定された [テーブル] から指定されたデータを FROM データからクエリします列名 (フィールド) SELECT 列名 FROM テーブル名 インスタンス -- 注: 複数の列を区切るには英語のカンマを使用してください。 selectusername、passwordfrom

See all articles