论坛源码分析--显示篇

在下小试牛刀,用perl编写了一个论坛程序,希望和大家分享.
好了,不阻碍大家的时间了,现在就让我们来看看源代码吧~~~~
本程序不用数据库,而是用txt文件来储存论坛信息的.

存储方式为:

1.存储在COUNTER.TXT里面的内容

subject‖3
坚决反对51的暴行‖adam‖3‖2001年2月10日,星期六,00:57:38‖
我说,ADAM你就非要开设这个题目不可吗?怎么每次都是这个......‖GBOY‖5‖2001年2月10日,星期六,15:51:35‖
哈哈哈,改名改名,好!!!!‖ally‖2‖2001年2月10日,星期六,20:49:34‖

(第一行是记录论坛数,subject‖3)
(第二行开始是记录论坛的主题等信息,分别是:主题‖创始人‖回复‖时间‖)


2.存储在data\1(ID号).txt
billow‖‖2001年2月16日,星期五,12:28:52‖哈哈!!!!!!!!!!!!<br>无聊!!!!!!!!!!!!!!!!
zsz‖‖2001年2月16日,星期五,12:34:09‖哈哈!!!!!!<br>  怎么样?够玩吧!!!!<br><br>‖

(分别是:回复人‖email‖时间‖内容‖)



下面的bbs_show.pl是实现部分~~

bbs_show.pl

#!/usr/bin/perl  #大家都应该知道这是什么吧~~~:P


#################下面是函数部分###################

##用get的方式获取输入信息.也就是说分析url中所带的参数

sub getinput_get
{ $input=$ENV{'QUERY_STRING'};
    @string=split(/&/,$input);
    foreach(@string)
    {
    $_ =~ s/\+/ /g;
    ($id, $value) = split(/=/, $_);
    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
    $id =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

    $GETINPUT{$id} = $value;
    }
return(%GETINPUT);
}








################显示论坛主版面信息###############

sub bbs_show {

  ############# 打印各式,用HTML各式
 
  print "Content-Type: text/html\n\n";
  print "<html><head><title>牛刀论坛</title>\n".
     "</head>".
 
  "<BODY bgColor=#ffffff leftMargin=0 topMargin=5>".
 
  "<div align=center>".
  "<center>".
  "<table border=0 width=750 cellpadding=0 cellspacing=0 height=68>".
  "<tr>".
   "<td width=191 height=68><img border=0 src=nocgi/top-1.gif width=204 height=71></td>".
   "<td width=555 height=68><img border=0 src=nocgi/top-2.gif width=430 height=71></td>".
  "</tr>".
  "</table>".
  "</center>".
  "</div>".
  "<HR SIZE=1 width=730>".
  "<br>".
  "<TABLE align=center border=0 cellPadding=2 cellSpacing=1 width=730><TBODY>".
   "<TR><TD align=middle vAlign=top width=200><A href=new.pl>".
   "<IMG border=0 src=nocgi/post.gif></A>";
  
 
  ########### 计算论坛 ############# 
  open(COUNTER,"<counter.txt")|| die "Can't Open counter.txt: $!\n"; ##打开一个叫counter.txt的文件
  $temp=<COUNTER>;
 
  ($subject,$number)=split(/‖/,$temp);##将文件的第一行作分析,得出主题数$number
  
 ############分页分析 以10主题为一页############### 

 if($number%10 != 0){        ### 如果$number可以被10整除,共分"$number/10+1"页
  $page_s=int($number/10) + 1;}
   else
   { $page_s=($number/10);     ###如果$number不可以被10整除,共分"$number/10"页
   }
 
  @temp=<COUNTER>;         ###把从第二行开始的数据储存到@temp上
   
    $ID_=$number-($page-1)*10;  ###获得当页面论坛的第一个主题ID
 



print
   "<td align=right><FONT class=mid>当前页:<B>${page}"."/"."${page_s}</B></td>".
  
   "</TD></TR></TBODY></TABLE>".
   "<HR SIZE=1 width=730>".
   "<TABLE align=center border=0 cellPadding=0 cellSpacing=0 width=750>".
   "<TBODY><TR><TD vAlign=top>".
   "<TABLE align=center border=0 cellPadding=4 cellSpacing=1 width=730>".
   "<TBODY><TR><TD align=middle bgColor=#6f6f6f width=45%>".
   "<FONT color=#ffffff>主题</FONT></TD>".
   "<TD align=middle bgColor=#6f6f6f width=12%>".
   "<FONT color=#ffffff>创建人</FONT></TD>".
   "<TD align=middle bgColor=#6f6f6f width=5%><FONT color=#ffffff>回复</FONT></TD>".
   "<TD align=middle bgColor=#6f6f6f width=28%><FONT color=#ffffff>始创论坛时间</FONT></TD>".
   "</TR>";


########### 打印论坛 ########## 
  for($i=$number-($page-1)*10;$i>=$number-($page)*10+1;$i--) ##用循环打印论坛
  {
 
  last if($i<=0);
  if($i%2==0){$color="cccccc";}
  else{$color="dedede";}
 
  ($subject,$name,$reply,$dotime)=split(/‖/,$temp[$i-1]);
  $reply--;
  print
  "<TR><TD bgColor=#$color class=mid>".
  "<A class=title href=bbs_show.pl?action=show&ID=$ID_>".
  "$subject</A></TD>".
  "<TD align=middle bgColor=#$color>".
  "<A href=kk target=_blank>".
  "$name</A></TD>".
  "<TD align=middle bgColor=#$color class=mid>$reply</TD>".
  "<TD align=middle bgColor=#$color><FONT color=#ff8800>$dotime</FONT></TD>";
  $ID_--;               ##打印一个主题后ID-1
  }

  close COUNTER;           ##关闭COUNTER.TXT


############################### 
  print "</TR></TBODY></TABLE>".
  "<HR SIZE=1 width=730>".
 






############ 打印分页 #############
  "<TABLE align=center border=0 cellPadding=4 cellSpacing=0 width=730>".
  "<TBODY>".
  "<TR>".
  "<TD class=mid vAlign=top><B>分页</B>:".
  "<FONT color=#999999><A href=bbs_show.pl?page=1>首页</A>". ##跳传到第一页
  "&nbsp;";
 
  $temp=$page-1;      ##打印跳传到前一页
  if($temp>0){
  print "<A href=bbs_show.pl?page=".$temp.">前页</A>";
  }else{print "前页";}   ##如果没有前一页,就不打印连接
 
  $temp=$page+1;      ##打印跳传到后一页
  if($temp<=$page_s){
  print "<A href=bbs_show.pl?page=".$temp.">后页</A>";
  }else{print "后页"; }  ##如果没有后一页,就不打印连接
 
  print
  "</FONT>&nbsp;".
  "<A href=bbs_show.pl?page=$page_s>尾页</A>".        ##跳传到最后一页
  "</TD>";
 
  print
  "<TD align=right vAlign=top>". ##用下拉菜单打印分页
  "<FORM action=display.php?forum_id=12&amp;order=last_time&amp;datelimit=5 method=post>".
  "<FONT class=mid>当前页:<B>${page}"."/"."${page_s}</B>".
  "&nbsp;&nbsp;".
  "转到第<SELECT name=page   onchange=javascript:location.href=this.options[this.selectedIndex].value>";

 print "<OPTION selected value=bbs_show.pl?page=$page>$page</OPTION>"; ##设定初始值为当前页面
  for($i=1;$i<=$page_s;$i++)
  {  if($i==$page){$i++;}
   last if($i>$page_s); ##如果分页打印结束,跳出循环
   print "<OPTION value=bbs_show.pl?page=$i>$i</OPTION>";
   }
  
  print
  "</SELECT>".
  "&nbsp;页</FONT>".
  "</TD></TR></TBODY>".
  "</TABLE>".

#####################################

  "<TABLE align=center border=0 cellPadding=2 cellSpacing=1 width=730><TBODY>".
  "<TR><TD align=middle vAlign=top width=200><A href=new.pl>".
  "<IMG border=0 src=nocgi/post.gif></A>".
  "</TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>";

  print "</body></html>\n";

  exit;
}




###############显示主题论坛########################

########################################
sub bbs_show_person
{
print "Content-Type: text/html\n\n";
print "<html><head><title>牛刀论坛</title>\n".
   "</head>".


  "<BODY bgColor=#ffffff leftMargin=0 topMargin=5>".
  "<div align=center>".
  "<center>".
  "<table border=0 width=750 cellpadding=0 cellspacing=0 height=68>".
  "<tr>".
  "<td width=191 height=68><img border=0 src=nocgi/top-1.gif width=204 height=71></td>".
  "<td width=555 height=68><img border=0 src=nocgi/top-2.gif width=430 height=71></td>".
  "</tr>".
  "</table>".
  "</center>".
  "</div>".
  "<HR SIZE=1 width=730>";

############# 计算个人论坛 ################


open(COUNTER,"<counter.txt")|| die "Can't Open counter.txt: $!\n";
@temp=<COUNTER>;      ##把内容存储到@TEMP
close COUNTER;
($subject,$name,$reply,$dotime)=split(/‖/,$temp[$ID]);
              ##把内容分割成 $subject,$name,$reply,$dotime 的变量 


        
$number=$reply;      ##计算有多少个页面(属于分页用途)
     if($number%10 != 0)  
      {
        $page_s=int($number/10)+1;
      }
      else
         { $page_s=($number/10);
         }

############ 打印论坛头 ############
 $reply--;        ##文件中行内容的个数减一为回复数(第一行是作者的内容,所以不可算在回复内)
 print
 "<TABLE align=center border=0 cellPadding=3 cellSpacing=0 width=730>".
 "<tr><TD>主 题 <font color=#336699>$ID</font>:".
 "<FONT class=big color=#993333><B>".
 "$subject</B></FONT></TD>".
 "</TR><TR><TD>创建人:<FONT class=mid color=#336699>".

 "$name</font>&nbsp;&nbsp;".
 " 创建时间:<FONT class=mid color=#336699>".
 "$dotime</font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;".
 "回复:<FONT class=mid color=#336699>".
 "$reply</font><FONT class=mid color=#993333>".
 "&nbsp; </font></TD> ".
 "</TR>".
 "</TABLE>".

 "<br>".
 "<TABLE align=center border=0 cellPadding=2 cellSpacing=1 width=730>".
 "<tr>".
 "<TD align=middle class=mid>".
 "<A href=new.pl><IMG border=0 src=nocgi/post.gif width=80 height=20></A>".
 "<A href=reply.pl?ID=$ID><IMG border=0 src=nocgi/reply.gif width=80 height=20></A>".
 "<A href=bbs_show.pl><IMG border=0 src=nocgi/theme_s.gif width=80 height=20></A>".
 
 "</TD>".
 
 "</TR>".
  "<td align=right><FONT class=mid>当前页:<B>${page}"."/"."${page_s}</B></td>".
 "</TABLE>".
  "<HR SIZE=0 width=730>";



########### 打印回复内容 #############3
 print
 "<TABLE align=center border=0 cellPadding=1 cellSpacing=2 width=730>".
"<tr><td>".
 "<TABLE align=center border=0 cellPadding=0 cellSpacing=0 width=730>".
 "<TR>".
 "<TD align=middle bgColor=#6f6f6f width=80%><FONT color=#ffffff>内容".
 "</FONT>".
 "</TD>".
 "</TR>".
 "</table>".
"</tr></td>";
###

   
    
    open(FILE,"<data/${ID}.txt"); ##打开论坛恢复文件(存储在data\1(ID号).txt)
    @temp=<FILE>;
    for($i=1+$page*10-10;$i<=$page*10;$i++) ##用一个FOR循环来打印
{
  last if($i>$number);
  if($i%2==0){$color="cccccc";}     ##如果是复数号内容,用color="cccccc"
     else{$color="dedede";}       ##如果是单数号内容,用color="dedede"
($name,$email,$dotime,$comments)=split(/‖/,$temp[$i-1]);
        
                     ##将内容分割成为 $name,$email,$dotime,$comments 的变量
     
 print  ## 用循环打印内容
"<tr><td>". 
 "<TABLE bgColor=#$color align=center border=0 cellPadding=0 cellSpacing=1 width=730>".
 "<tr width=100%>".
  "<TD width=60%><IMG align=ABSCENTER border=0 src=nocgi/icon1.gif>".
     "<FONT color=#336699>$name</FONT></TD>".
  "<TD valign=bottom width=50%><FONT color=#336699>发表于:$dotime</FONT></TD>".
  "<TD align=right><A href=http:// target=_blank>". ##编辑贴子还没写 :P
    "<IMG alt=编辑帖子 border=0 src=nocgi/edit.gif></A></TD>".
 "</tr>".
 "<tr>".
   "<TD width=80% colSpan=3 height=1%><HR SIZE=1></TD>".
 "</tr>".
 "<tr>".
   "<td width=80% colSpan=3>$comments<BR>".
 "$email<br>".
 "</tr>".
 "</TR></table>".
"</tr></td>"; 
     }               ## 循环结束
     close FILE;

##################################
 print
"<tr><td>".
 "<TABLE align=center border=0 cellPadding=4 cellSpacing=2 width=730>".
 "<TR align=right bgColor=#6f6f6f><TD>&nbsp;</TD></TR>".
 "</TABLE>".
"</tr></td>".
 "</TABLE>".


##### 打印分页 #############  (和上面所说的显示论坛主版面信息中打印分页原理一样,所以省略)
  "<TABLE align=center border=0 cellPadding=4 cellSpacing=0 width=730>".
  "<TBODY>".
  "<TR>".
  "<TD class=mid vAlign=top><B>分页</B>:".
  "<FONT color=#999999><A href=bbs_show.pl?action=show&ID=$ID&page=1>首页</A>".
  "&nbsp;";
 
  $temp=$page-1;
  if($temp>0){
  print "<A href=bbs_show.pl?action=show&ID=$ID&page=".$temp.">前页</A>";
  }else{print "前页";}
  $temp=$page+1;
  if($temp<=$page_s){
  print "<A href=bbs_show.pl?action=show&ID=$ID&page=".$temp.">后页</A>";
  }else{print "后页"; }
 
  print
  "</FONT>&nbsp;".
  "<A href=bbs_show.pl?action=show&ID=$ID&page=$page_s>尾页</A>".
  "</TD>";
 
  print
  "<TD align=right vAlign=top>".
  "<FORM action=display.php?forum_id=12&amp;order=last_time&amp;datelimit=5 method=post>".
  "<FONT class=mid>当前页:<B>${page}"."/"."${page_s}</B>".
  "&nbsp;&nbsp;".
  "转到第<SELECT name=page onchange=javascript:location.href=this.options[this.selectedIndex].value>";

 print "<OPTION selected value=bbs_show.pl?action=show&ID=$ID&page=$page>$page</OPTION>";
  for($i=1;$i<=$page_s;$i++)
  {  if($i==$page){$i++;}
   last if($i>$page_s);
   print "<OPTION value=bbs_show.pl?action=show&ID=$ID&page=$i>$i</OPTION>";
   }
  
  print
  "</SELECT>".
  "&nbsp;页</FONT>".
  "</TD></TR></TBODY>".
  "</TABLE>".




############################


 "<table align=center><HR SIZE=1 width=730><TABLE align=center border=0 cellPadding=2 cellSpacing=1 width=730>".
 "<TBODY>".
 "<tr>".
 "<TD align=middle class=mid>".
 "<A href=new.pl><IMG border=0 src=nocgi/post.gif width=80 height=20></A>".
 "<A href=reply.pl?ID=$ID><IMG border=0 src=nocgi/reply.gif width=80 height=20></A>".
 "<A href=bbs_show.pl><IMG border=0 src=nocgi/theme_s.gif width=80 height=20></A>".
 "</TD></TR></TBODY></TABLE></table></TBODY>".

 "</body></html>";


exit;

}

#### OK啦,全部打印完了



################# 以上是函数库 ##############################


getinput_get(); ##获取URL中的参数(例如:http://bbs_show.pl?action=show&ID=3)
         ##则是打印论坛主题三中的内容

$action=$GETINPUT{'action'};
$ID=$GETINPUT{'ID'};
 if($action eq "show")  ##如果action=show,显示主题论坛
  {
    if($GETINPUT{'page'}eq "")
           {$page=1;} ##给予PAGE的初始值page=1
       else
         {$page=$GETINPUT{'page'};}
  bbs_show_person();     ## 开始显示

  }
  else            ##如果没有参数,显示论坛主版面信息
  {
    if($GETINPUT{'page'}eq "")
         {$page=1;}   ##给予PAGE的初始值page=1
       else
         {$page=$GETINPUT{'page'};}
  bbs_show();        ## 开始显示
  }


 注意,以上的只是核心的源码,其他的版面设定给省略了