一个统计程序总行数的程序


<? 
/**************************************************************** 
程序行数统计程序 count.php 

本程序独立运行,不需要任何数据库支持、头文件 
本程序已在 Apache for Linux,Apache for Windows, IIS下测试通过 

建立于:2001年1月19日 by Dallas 

最近更新 更新人员 内容 

2001年2月20日 Dallas 加入文件说明 
2001年2月22日 Dallas 加入统计文件行数、大小功能 
2001年2月23日 Dallas 加入统计每行字符数的功能 
加入选择目录进行统计的功能 
自动根据操作系统选择部分参数,确保显示正确 
2001年2月25日 Dallas 加入选择文件类型的功能 
*****************************************************************/ 

//是否显示调试信息 
$DEBUG_LOCAL false

//预先定义的文档类型 
$FILE_TYPES = array ( 
array ( 
"dfm"
"c"
"cpp"
"h"
"hpp"
"pas"
"php"
"htm"
"HTML"
"js"
"css"
"sh"
"inc" 
), 
array ( 
"Delphi Form"
"C 语言源程序"
"C++ 源程序"
"C 语言头文件"
"C++ 头文件"
"Pascal 源程序"
"PHP 文件"
"HTML 文件"
"HTML 文件"
"Java Script 文件"
"层叠样式表文档"
"Shell Script 文件"
"Include 文件" 

); 

//需要排除,不参与统计的文件 
$FILES_EXCLUDE = array ( 
"count.php" => true
   
"info.php" => true 
  
); 
   
  
$FILES_TOTAL 0//文件总数 
  
$LINES_TOTAL 0//文件总行数 
  
$SIZE_TOTAL 0//文件总大小 

//根据是否在 Windows 下运行确定几个参数 
  
if( EregI"win32"$SERVER_SOFTWARE ) or EregI"iis"$SERVER_SOFTWARE ) ) { 
   
$URL_SELF $PATH_INFO
   
$PATH_CURRENT StripSlashesDirName$PATH_TRANSLATED ) ); 
   
$DIR_SEPARATOR "\\"
  } else { 
   
$URL_SELF $PHP_SELF
   
$PATH_CURRENT DirName$SCRIPT_FILENAME ); 
   
$DIR_SEPARATOR "/"
  } 
  
$DIR_SUB false//储存当前目录状态,是否在子目录中 
  
$DIR_NAME $PATH_CURRENT
   
//本函数读取指定目录中的相关文件 
//输入参数:要读取的目录名,如果省略则为当前目录 
//返回参数:存有该目录文件名的数组 
function GetFiles$path "." ) { 
global 
$FILE_TYPE$FILES_EXCLUDE$DEBUG_LOCAL$PATH_CURRENT$DIR_NAME$DIR_SUB$DIR_SEPARATOR
if( 
$path != "." ) { 
$DIR_NAME $PATH_CURRENT.$DIR_SEPARATOR.$path
ChDir$path ); //进入该目录 
$DIR_SUB true
} else { 
$DIR_SUB false

$handle OpenDir"." ); 
$i 0
while ( 
$file readdir$handle ) ) { 
if( 
$DEBUG_LOCAL 
echo 
"原有文件 $file
\n"
//不是普通文件的不统计,这样就过滤掉了连接,目录 
if( !Is_File$file ) ) 
continue; 
if( 
$DEBUG_LOCAL 
echo 
"通过is_file的文件 $file
\n"
//取出从文件名最后一个'.'开始以后的子串为文件类型,转为小写 
$TYPE StrToLowerSubStr$fileStrRPos$file'.' ) + ) ); 
//如果文件类型不在预定义的类型中,也不统计 
if( Empty( $FILE_TYPE$TYPE ] ) ) 
continue; 
if( 
$DEBUG_LOCAL 
echo 
"通过预定义类型的文件 $file
\n"
//如果在排除的文件中,也不统计 
if( $FILES_EXCLUDE$file ] ) 
continue; 
$files$i++ ] = $file
if( 
$DEBUG_LOCAL 
echo 
"通过排除的文件 $file
\n"

CloseDir$handle );  
//如果有内容则排序,否则返回原目录 
if( COUNT$files ) > ) { 
Sort$files ); 
} else { 
if( 
$DIR_SUB 
ChDir".." ); 

return 
$files


//本函数格式统计并输出文件的相关信息 
//输入参数:存有文件名的数组 
//返回参数:无 
function ShowResults$files$display_method "ALL" ) { 
global 
$DIR_NAME$FILE_TYPE$PATH_CURRENT$FILES_TOTAL$SIZE_TOTAL$LINES_TOTAL,$DIR_SUB
if( 
$display_method != "TOTAL" ) { 
echo 
"<P> 
<TABLE CELLSPACING=1 WIDTH=600> 
 <CAPTION>目录 $DIR_NAME</CAPTION> 
 <TR> 
  <TH NOWRAP>序号</TH> 
  <TH NOWRAP>文件名</TH> 
  <TH NOWRAP>文件类型</TH> 
  <TH NOWRAP>文件大小</TH> 
  <TH NOWRAP>文件行数</TH> 
  <TH NOWRAP>每行字符</TH> 
 </TR>
\n"
  } 
  
$size_subtotal 0
  
$lines_subtotal 0
for( 
$i 0$i Count$files ); $i++ ) { 
$size FileSize$files$i ] ); 
$size_subtotal += $size
$contents File$files$i ] ); 
$line Count$contents ); 
$lines_subtotal += $line
//取出从文件名最后一个'.'开始以后的子串为文件类型,转为小写 
$TYPE StrToLowerSubStr$files$i ], StrRPos$files$i ], '.' ) + ) ); 
if( 
$line != 
$chars_per_line Round$size $line ); 
else 
$chars_per_line 0
if( 
$lines_subtotal != 
$chars_per_line_sub Round$size_subtotal $lines_subtotal ); 
else 
$chars_per_line_sub 0
$sequence $i 1
if( 
$display_method == "ALL" ) { 
echo 
" <TR> 
  <TD ALIGN=CENTER>$sequence</TD> 
  <TD NOWRAP>$files
[$i]</TD> 
  <TD NOWRAP>$FILE_TYPE
[$TYPE]</TD> 
  <TD ALIGN=RIGHT>$size</TD> 
  <TD ALIGN=RIGHT>$line</TD> 
  <TD ALIGN=CENTER>$chars_per_line</TD> 
 </TR>
\n"
  } 

if( 
$display_method != "TOTAL" ) { 
echo 
" <TR> 
  <TD CLASS=RESULT ALIGN=CENTER>小计</TD> 
  <TD CLASS=RESULT ALIGN=CENTER>$i 个文件</TD> 
  <TD CLASS=RESULT> </TD> 
  <TD CLASS=RESULT ALIGN=RIGHT NOWRAP>$size_subtotal 字节</TD> 
  <TD CLASS=RESULT ALIGN=RIGHT>$lines_subtotal 行</TD> 
  <TD CLASS=RESULT ALIGN=CENTER NOWRAP>平均每行 $chars_per_line_sub 字符</TD> 
 </TR> 
</TABLE>
\n"

if(
$DIR_SUB
ChDir".." ); 
$FILES_TOTAL += $i
$SIZE_TOTAL += $size_subtotal
$LINES_TOTAL += $lines_subtotal


//本函数显示总的统计结果 
function ShowTotal() { 
global 
$FILES_TOTAL$SIZE_TOTAL$LINES_TOTAL
if( 
$LINES_TOTAL != 
$chars_per_line_total Round$SIZE_TOTAL $LINES_TOTAL ); 
else 
$chars_per_line_total 0
echo 
"<P> 
<TABLE CELLSPACING=1 WIDTH=600> 
 <CAPTION>以上总计</CAPTION> 
 <TR> 
  <TH NOWRAP>文件总数</TH> 
  <TH NOWRAP>总大小</TH> 
  <TH NOWRAP>总行数</TH> 
  <TH NOWRAP>总平均每行字符数</TH> 
 </TR> 
 <TR> 
  <TD CLASS=RESULT ALIGN=CENTER>$FILES_TOTAL 个文件</TD> 
  <TD CLASS=RESULT ALIGN=CENTER>$SIZE_TOTAL 字节</TD> 
  <TD CLASS=RESULT ALIGN=CENTER>$LINES_TOTAL 行</TD> 
  <TD CLASS=RESULT ALIGN=CENTER>$chars_per_line_total 字符</TD> 
 </TR> 
</TABLE>
\n"

?> 
<HTML> 

<HEAD> 

<TITLE>文件统计</TITLE> 

<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="TEXT/HTML; CHARSET=GB2312"> 

<STYLE> 
TH { 
FONT-FAMILY: 楷体_GB2312; 
BACKGROUND-COLOR: YELLOW; 
FONT-SIZE: 16PX; 

TD { 
BACKGROUND-COLOR: #88FF88; 
FONT-SIZE: 14PX; 

TD.LEVEL1 { 
BACKGROUND-COLOR: #FFFFFF; 
FONT-SIZE: 14PX; 

TD.RESULT { 
BACKGROUND-COLOR: LIGHTBLUE; 
FONT-SIZE: 14PX; 

H2 { 
FONT-FAMILY: 楷体_GB2312; 
COLOR: BLUE; 
FONT-SIZE: 24PX; 

CAPTION { 
COLOR: BLUE; 
FONT-SIZE: 18PX; 

A.F12 { 
CURSOR: HAND; 
COLOR: BLUE; 
FONT-SIZE: 12PX; 

</STYLE> 

<SCRIPT LANGUAGE="JavaScript"> 
function ReverseFileTypes( this_form ) { 
for ( var i = 0; i < this_form.elements.length; i++ ) { 
var e = this_form.elements[ i ]; 
srcID = e.id.substr( 0, 2 ); 
if( srcID == "FT" ) { 
if(e.checked) 
e.checked = false; 
else 
e.checked = true; 




function ReverseDirs( this_form ) { 
for ( var i = 0; i < this_form.elements.length; i++ ) { 
var e = this_form.elements[ i ]; 
srcID = e.id.substr( 0, 3 ); 
if( srcID == "DIR" ) { 
if( e.checked ) 
e.checked = false; 
else 
e.checked = true; 




function TotalClick( this_form ) { 
if( this_form.TOTAL_ONLY.checked ) 
this_form.SUB_DIR_ONLY.checked = false; 


function SubDirsClick( this_form ) { 
if( this_form.SUB_DIR_ONLY.checked ) 
this_form.TOTAL_ONLY.checked = false; 


function SubDirsTextClick( this_form ) { 
if( this_form.SUB_DIR_ONLY.checked ) 
this_form.SUB_DIR_ONLY.checked = false; 
else { 
this_form.SUB_DIR_ONLY.checked = true; 
this_form.TOTAL_ONLY.checked = false; 



function TotalTextClick( this_form ) { 
if( this_form.TOTAL_ONLY.checked ) 
this_form.TOTAL_ONLY.checked = false; 
else { 
this_form.TOTAL_ONLY.checked = true; 
this_form.SUB_DIR_ONLY.checked = false; 


</SCRIPT> 
  
</HEAD> 

<BODY BGCOLOR="#ffffff" TOPMARGIN="0" LEFTMARGIN="0" MARGINWIDTH="0" MARGINHEIGHT="0"> 

<CENTER> 
<P>


<H2>文件统计</H2> 
<? 
$handle 
OpenDir"." ); 
$i 0
while ( 
$file ReadDir$handle ) ) { 
if( 
$DEBUG_LOCAL 
echo 
"文件名: $file
\n"
//如果不是目录则跳过 
if( !Is_Dir$file ) ) 
continue; 
//不显示父目录 
if( $file == ".." 
continue; 
$dirs$i++ ] = $file
if( 
$DEBUG_LOCAL 
echo 
"目录名: $file
\n"

CloseDir$handle ); 
echo 
"<P> 
<FORM METHOD=POST ACTION='$URL_SELF' NAME=DIRFORM> 

<TABLE CELLSPACING=1 WIDTH=100%> 
 <TR VALIGN=TOP> 
  <TD CLASS=LEVEL1 ALIGN=LEFT>
\n"
   echo 
"<!-- Begin File Types Table --> 
<TABLE CELLSPACING=1 WIDTH=300 BGCOLOR=#DDDDDD> 
 <CAPTION NOWRAP>统计以下文件类型</CAPTION> 
 <TR> 
  <TD COLSPAN=4> <A ID='SWITCH_FILE_TYPE' CLASS='F12' onClick='ReverseFileTypes(DIRFORM)'>切换选择状态</TD> 
 </TR> 
 <TR> 
  <TH ALIGN=CENTER WIDTH=15%>序号</TH> 
  <TH ALIGN=CENTER WIDTH=15%>选择</TH> 
  <TH ALIGN=CENTER WIDTH=25%>文件后缀</TH> 
  <TH ALIGN=CENTER>文件类型</TH> 
 </TR>\n"

  for( 
$i 0$i Count$FILE_TYPES] ); $i++ ) { 
$sequence $i 1
$check "CHECKED"
//默认不统计 Delphi Form 的行数 
if( $FILE_TYPES][ $i ] == "dfm" 
$check ""
echo 
" <TR> 
  <TD ALIGN=CENTER>$sequence</TD> 
  <TD ALIGN=CENTER><INPUT ID='FT$i' NAME='FILE_TYPE_SELECTED
[]' TYPE=CHECKBOX $check VALUE='".$FILE_TYPES][ $i ]."'></TD> 
  <TD ALIGN=CENTER>"
.StrToUpper$FILE_TYPES][ $i ] )."</TD> 
  <TD NOWRAP> "
.$FILE_TYPES][ $i ]."</TD> 
 </TR>\n"

  } 
echo 
" <TR> 
  <TD COLSPAN=4> <A ID='SWITCH_FILE_TYPE' CLASS='F12' onClick='ReverseFileTypes(DIRFORM)'>切换选择状态</TD> 
 </TR> 
</TABLE> 
<!-- End File Types Table -->\n"

echo 
"  </TD> 
  <TD CLASS=LEVEL1> </TD> 
  <TD CLASS=LEVEL1>\n"

echo 
"<!-- Begin Directorys Table --> 
<TABLE CELLSPACING=1 WIDTH=400 BGCOLOR=#DDDDDD> 
 <CAPTION>当前目录 $PATH_CURRENT</CAPTION> 
 <TR> 
  <TD COLSPAN=3> <A ID='SWITCH_DIR' CLASS='F12' onClick='ReverseDirs(DIRFORM)'>切换选择状态</TD> 
 </TR> 
 <TR> 
  <TH ALIGN=CENTER WIDTH=15%>序号</TH> 
  <TH ALIGN=CENTER WIDTH=15%>选择</TH> 
  <TH ALIGN=CENTER>子目录</TH> 
 </TR>
\n"
for( 
$i 0$i count$dirs ); $i++ ) { 
$sequence $i 1
echo 
" <TR> 
  <TD ALIGN=CENTER>$sequence</TD> 
  <TD ALIGN=CENTER><INPUT ID=DIR$i NAME=DIR_SELECTED
[] TYPE=CHECKBOX CHECKED VALUE='".$dirs$i ]."'></TD> 
  <TD NOWRAP ALIGN=LEFT> "
.$dirs$i ]."</TD> 
 </TR>\n"


echo 
" <TR> 
  <TD COLSPAN=3> <A ID=SWITCH_DIR CLASS=F12 onClick='ReverseDirs(DIRFORM)'>切换选择状态</TD> 
 </TR> 
 <TR> 
  <TD COLSPAN=3> 
   <INPUT ID=SUB_DIR_ONLY NAME=SUB_DIR_ONLY TYPE=CHECKBOX VALUE=1 onClick='SubDirsClick(DIRFORM)'> 
    <A CLASS='F12' onClick='SubDirsTextClick(DIRFORM)'>仅显示统计结果 
      <INPUT ID=TOTAL_ONLY NAME=TOTAL_ONLY TYPE=CHECKBOX VALUE=1 CHECKED onClick='TotalClick(DIRFORM)'> 
    <A CLASS='F12' onClick='TotalTextClick(DIRFORM)'>仅显示总结果 
  </TD> 
 </TR> 
</TABLE> 
<!-- End Directorys Table -->\n"

echo 
"  </TD> 
  <TD CLASS=LEVEL1 WIDTH=100%> </TD> 
 </TR> 
</TABLE> 

<CENTER> 
<INPUT ID='COUNT' NAME='COUNT' TYPE=SUBMIT VALUE=' 统计 '> 
</CENTER> 

</FORM>\n\n"


  if( 
$COUNT ) { 
//根据文件类型原型数组生成一个索引数组 
   
for( $i 0$i Count$FILE_TYPES] ); $i++ ) { 
$FILE_TYPE_INDEX$FILE_TYPES][ $i ] ] = $FILE_TYPES][ $i ]; 

//根据选中的文件类型再生成文件类型索引数组 
for( $i 0$i Count$FILE_TYPE_SELECTED ); $i++ ) { 
$FILE_TYPE$FILE_TYPE_SELECTED$i ] ] = $FILE_TYPE_INDEX$FILE_TYPE_SELECTED$i ] ]; 

$display_method "ALL"
if( 
$SUB_DIR_ONLY 
$display_method "SUB"
if( 
$TOTAL_ONLY 
$display_method "TOTAL"
for( 
$i=0$i Count$DIR_SELECTED ); $i++ ) { 
$files GetFiles$DIR_SELECTED$i ] ); 
if( 
Count$files ) > ) { 
ShowResults$files$display_method ); 


ShowTotal(); 
  } 
  echo 
"<P>


</BODY> 
</HTML>"

?>