在PHP編程中,如果你使用文本型數據庫,也許會為它的分類排序問題感到頭痛。下面小陽介紹一下如何運用PHP結合JavaScript腳本實現這個功能:如下圖,當用戶點擊相應的標題類別時,如果該類別與原類別不同,則按相應類別相同的升降序排列;當點擊類別與原類別相同,則按該類別與原來相反的順序排列。(即假如圖中把鼠標放至“歌手”標題,將提示“按[歌手][升序]排列”。)
例子中文本數據庫的格式為:每行的信息都各保存在一個文件下,文件內容格式為“歌曲名稱|歌手|大小”。例如文件“找一個字代替.txt”的內容是“找一個字代替|卓依婷|48554”,每個文件都只有一行,且保存在“data”目錄下。
分類排序的思路是:將要排序的該類別所在信息讀取到$sort_array[]數組中,對$sort_array[]進行排列,得到新排列的下標的數組$key_array[],再按下標的數組依次把文件讀出來即可。
下面我們編寫這個PHP文件。
<?
//給分類排序予默認值:
if (empty($sorted)) $sorted="musicname"; //排序類別
if (empty($dir)) $dir=1; //升降序
?>
<HTML><HEAD>
<meta http-equiv="Content-Type" content="text/html;charset=gb2312">
<TITLE>歌曲列表</TITLE>
<style TYPE="text/css">
<!--
td{font-size: 9pt}
-->
</style>
</HEAD>
<BODY>
<!-- 以下是JavaScript腳本,結合PHP而成 -->
<script language="javascript">
sorted="<?echo $sorted;?>"; //讀取地址欄的類別信息
dir=parseInt("<?echo $dir;?>"); //讀取地址欄的升降序信息
function sortby(obj){ //本函數用於指定點擊的標題欄的鏈接地址,傳遞分類排序信息
sorted==obj.ename ? mydir=-dir : mydir=dir; //如果排序類別就是所點擊的類別,則改變升降序
obj.href=location.pathname+"?sorted="+obj.ename+"&dir="+mydir; //指定鏈接地址
}
function tips(obj){ //本函數定義鏈接和狀態欄的提示信息
sorted==obj.ename ? mydir=-dir:mydir=dir;
obj.href="sortby: 按["+obj.chname+"]["+ (mydir>0?"降序":"升序") +"]排列";
obj.title="按["+obj.chname+"]["+ (mydir>0?"降序":"升序") +"]排列";
/* 注意上兩式的格式。首先第一行中只是只是指定該鏈接的路徑為“sortby: 按……排列”,但狀態欄中卻沒有出現“http://”等字樣。
實際上只要鏈接以不含空格和特殊字符的英文字串加“:”號,浏覽器即認為這不是相對路徑,狀態欄將按鏈接路徑顯示(即使它是不合法的)。
其次上兩式右邊都插入了一個三元運算子(“?:”),單獨看來括號裡的語句是不合JavaScript語法的。這種句式比較少見。
當然你也可以寫成if...else..的格式。
下面的PHP程序中小陽也用了一句類似的格式,供讀者參考。
*/
}
</script>
<TABLE align=center bgColor="#0099CC" border=0 cellPadding=0 cellSpacing=0 width=500>
<TBODY>
<TR>
<TD height="20" align="center" bgColor=#799ADD><font color="#FFFFFF">歌曲列表</font></TD>
</TR>
<TR>
<TD> <TABLE border=0 cellPadding=1 cellSpacing=1 width="100%">
<TBODY>
<TR bgColor=#becfed>
<?
$sortdownsrc="img/sortdown.gif"; //向下箭頭的圖片,顯示在降序排列的標題旁
$sortupsrc="img/sortup.gif"; //向上箭頭的圖片,顯示在升序排列的標題旁
function printtitle(){ //本函數用於輸出標題鏈接和箭頭圖片
global $ename,$sorted,$dir,$sortdownsrc,$sortupsrc,$chname;
echo "<a href='#' onmouseover='tips(this)' onmousedown='sortby(this)' chname='$chname' ename='$ename'><font color='#0000FF'>$chname</font></a>";
/*上式輸出中給<a>標簽自己定義了兩個屬性“chname”和“ename”。“chname”是標題的中文名,用於顯示;“ename”是標題的英文名,用於分類
在上面JavaScript代碼中的sortby()函數中就直接利用了它們。這個方法也許值得讀者借鑒。
*/
if($sorted==$ename){ //如果標題類別就是所排序的類別,則顯示箭頭圖片
echo "<img src='". ($dir>0?$sortdownsrc:$sortupsrc) ."'>";
//上一行的插入三元運算子的格式在前面已經介紹過。
}
}
?> <!--輸出標題欄表格-->
<? $ename="musicname"; $chname="歌曲名稱"; ?> <TD align=center> <? printtitle(); ?></TD>
<? $ename="singer"; $chname="歌手"; ?> <TD align=center> <? printtitle(); ?></TD>
<? $ename="musicsize"; $chname="大小"; ?> <TD align=center> <? printtitle(); ?></TD>
<?
$i=1;
//以下讀取數據庫文件夾裡的文件數據。
$open=opendir("data/");
//第一次讀取
while ($filename=readdir($open)) {
if (filesize("data/".$filename)>0){
$filecontent=file("data/".$filename);
//將讀到的數據劃分到各變量中:
$msgs_info=explode("|",$filecontent[0]);
$musicname=$msgs_info[0];
$singer=$msgs_info[1];
$musicsize=$msgs_info[2];
/* 把要排序的類的值讀到$sort_array[]中以便排序,下式用到了雙重變量,即把從地址欄傳遞過來的分類值作為變量。
所以上面三式的變量名必須與各鏈接標題的“ename”相對應:
*/
$sort_array[$i]=${$sorted};
//把對應的文件名讀到$filename_array[]中,以便和排序後的下標對應。
$filename_array[$i]=$filename;
$i++;
}
}
$totalfile=count($sort_array); //文件總數
if($totalfile!=0){
//下面函數對$sort_array[]進行升序或降序排列:
$dir>0 ? asort($sort_array) : arsort($sort_array);
/* 讀取排列後的新順序:
注意到$sort_array[]的下標是從1開始的,因為該函數不能處理0為下標,在PHP中0認為是FALSE,在for()的條件中會中斷循環。
*/
$i=1;
for(reset($sort_array); $key = key($sort_array); next($sort_array)) {
//令 $key_array[] 為排好的數組下標
$key_array[$i] = $key;
$i++;
}
for ($i=1;$i<=$totalfile;$i++){
// 因$key_array[]是排好的數組下標,把它應用到$filename_array[]中就行:
//第二次讀取文件,按排好的文件讀取,並輸出:
$filecontent=file("data/".$filename_array[$key_array[$i]]);
$msgs_info=explode("|",$filecontent[0]);
$musicname=$msgs_info[0];
$singer=$msgs_info[1];
$musicsize=$msgs_info[2];
echo "<TR bgColor=#ebf1f7> \n";
echo "<td align=left> $musicname</td> \n";
echo "<td align=left> $singer</td> \n";
echo "<td align=left> $musicsize KB</td> \n";
echo "</TR> \n";
}
}
closedir($open);
?> </TR>
</TBODY>
</TABLE></TD>
</TR>
</TBODY>
</TABLE>
</BODY>
</HTML>
OK,我們的程序已經寫好了。程序中讀了兩次文件,這樣可能速度可能慢些;當然可以改為第一次讀的時候就把文件的內容存儲到一個數組中,這樣免了第二次的讀取,但這樣需要占用較多的服務器內存,為安全起見只好犧牲一點速度了。
今天小陽不但向大家介紹了文本數據庫的分類排序方法,還順便較詳細地介紹了PHP和JavaScript相結合的編程方法、三元運算子的特殊應用、狀態欄的顯示規律和HTML元素自定義屬性的應用等。好了,在服務器上運行一下剛才編好的PHP文件看看。細心的讀者很快就會發現還缺了什麼。對了,是分頁顯示!可惜,限於篇幅,這裡就不介紹了,你自己去完善它吧。