Discuz教程网

PHP统计目录下的文件总数及代码行数(不包括注释及空行)

[复制链接]
authicon 09927306 发表于 2011-1-18 12:16:28 | 显示全部楼层 |阅读模式

  1. <?php
  2. /**
  3. * @author xiaoxiao <x_824@sina.com> 2011-1-12
  4. * @link http://xiaoyaoxia.cnblogs.com/
  5. * @license
  6. * 统计目录下的文件行数及总文件数··去除注释
  7. */
  8. $obj = new CaculateFiles();
  9. //如果设置为false,这不会显示每个文件的信息,否则显示
  10. $obj->setShowFlag(false);
  11. //会跳过所有All开头的文件
  12. $obj->setFileSkip(array(\'All\'));
  13. $obj->run("D:\\PHPAPP\\php\\_tests");
  14. //所有文件,(默认格式为.php)
  15. $obj->setFileSkip(array());
  16. $obj->run("D:\\PHPAPP\\php");
  17. $obj->setShowFlag(true);
  18. //跳过所有I和A开头的文件,(比如接口和抽象类开头)
  19. $obj->setFileSkip(array(\'I\', \'A\'));
  20. $obj->run("D:\\PHPAPP\\php");

  21. /**
  22. * 执行目录中文件的统计(包括文件数及总行数
  23. *
  24. * 1、跳过文件的时候:
  25. * 匹配的规则只是从文件名上着手,匹配的规则也仅限在开头。
  26. * 2、跳过文件中的注释行:
  27. * 匹配的规则只是从注释段落的头部匹配,如果出现// 及 *及 #及/*开头的行及空行会被跳过。所以类似/*这种多汗注释,每行的开头都必须加上*号,否则无法匹配到这种的注释。
  28. * 3、目录过滤:
  29. * 匹配的规则是从目录名的全名匹配
  30. */
  31. class CaculateFiles {
  32. /**
  33. * 统计的后缀
  34. */
  35. private $ext = ".php";
  36. /**
  37. * 是否显示每个文件的统计数
  38. */
  39. private $showEveryFile = true;
  40. /**
  41. * 文件的的跳过规则
  42. */
  43. private $fileSkip = array();
  44. /**
  45. * 统计的跳过行规则
  46. */
  47. private $lineSkip = array("*", "/*", "//", "#");
  48. /**
  49. * 统计跳过的目录规则
  50. */
  51. private $dirSkip = array(".", "..", \'.svn\');
  52. public function __construct($ext = \'\', $dir = \'\', $showEveryFile = true, $dirSkip = array(), $lineSkip = array(), $fileSkip = array()) {
  53. $this->setExt($ext);
  54. $this->setDirSkip($dirSkip);
  55. $this->setFileSkip($fileSkip);
  56. $this->setLineSkip($lineSkip);
  57. $this->setShowFlag($showEveryFile);
  58. $this->run($dir);
  59. }
  60. public function setExt($ext) {
  61. trim($ext) && $this->ext = strtolower(trim($ext));
  62. }
  63. public function setShowFlag($flag = true) {
  64. $this->showEveryFile = $flag;
  65. }
  66. public function setDirSkip($dirSkip) {
  67. $dirSkip && is_array($dirSkip) && $this->dirSkip = $dirSkip;
  68. }
  69. public function setFileSkip($fileSkip) {
  70. $this->fileSkip = $fileSkip;
  71. }
  72. public function setLineSkip($lineSkip) {
  73. $lineSkip && is_array($lineSkip) && $this->lineSkip = array_merge($this->lineSkip, $lineSkip);
  74. }
  75. /**
  76. * 执行统计
  77. * @param string $dir 统计的目录
  78. */
  79. public function run($dir = \'\') {
  80. if ($dir == \'\') return;
  81. if (!is_dir($dir)) exit(\'Path error!\');
  82. $this->dump($dir, $this->readDir($dir));
  83. }
  84. /**
  85. * 显示统计结果
  86. * @param string $dir 目录
  87. * @param array $result 统计结果(包含总行数,有效函数,总文件数
  88. */
  89. private function dump($dir, $result) {
  90. $totalLine = $result[\'totalLine\'];
  91. $lineNum = $result[\'lineNum\'];
  92. $fileNum = $result[\'fileNum\'];
  93. echo "*************************************************************\\r\\n<br/>";
  94. echo $dir . ":\\r\\n<br/>";
  95. echo "TotalLine: " . $totalLine . "\\r\\n<br/>";
  96. echo "TotalLine with no comment and empty: " . $lineNum . "\\r\\n<br/>";
  97. echo \'TotalFiles:\' . $fileNum . "\\r\\n<br/>";
  98. }
  99. /**
  100. * 读取目录
  101. * @param string $dir 目录
  102. */
  103. private function readDir($dir) {
  104. $num = array(\'totalLine\' => 0, \'lineNum\' => 0, \'fileNum\' => 0);
  105. if ($dh = opendir($dir)) {
  106. while (($file = readdir($dh)) !== false) {
  107. if ($this->skipDir($file)) continue;
  108. if (is_dir($dir . \'/\' . $file)) {
  109. $result = $this->readDir($dir . \'/\' . $file);
  110. $num[\'totalLine\'] += $result[\'totalLine\'];
  111. $num[\'lineNum\'] += $result[\'lineNum\'];
  112. $num[\'fileNum\'] += $result[\'fileNum\'];
  113. } else {
  114. if ($this->skipFile($file)) continue;
  115. list($num1, $num2) = $this->readfiles($dir . \'/\' . $file);
  116. $num[\'totalLine\'] += $num1;
  117. $num[\'lineNum\'] += $num2;
  118. $num[\'fileNum\']++;
  119. }
  120. }
  121. closedir($dh);
  122. } else {
  123. echo \'open dir <\' . $dir . \'> error!\' . "\\r";
  124. }
  125. return $num;
  126. }
  127. /**
  128. * 读取文件
  129. * @param string $file 文件
  130. */
  131. private function readfiles($file) {
  132. $str = file($file);
  133. $linenum = 0;
  134. foreach ($str as $value) {
  135. if ($this->skipLine(trim($value))) continue;
  136. $linenum++;
  137. }
  138. $totalnum = count(file($file));
  139. if (!$this->showEveryFile) return array($totalnum, $linenum);
  140. echo $file . "\\r\\n";
  141. echo \'TotalLine in the file:\' . $totalnum . "\\r\\n";
  142. echo \'TotalLine with no comment and empty in the file:\' . $linenum . "\\r\\n";
  143. return array($totalnum, $linenum);
  144. }
  145. /**
  146. * 执行跳过的目录规则
  147. * @param string $dir 目录名
  148. */
  149. private function skipDir($dir) {
  150. if (in_array($dir, $this->dirSkip)) return true;
  151. return false;
  152. }
  153. /**
  154. * 执行跳过的文件规则
  155. * @param string $file 文件名
  156. */
  157. private function skipFile($file) {
  158. if (strtolower(strrchr($file, \'.\')) != $this->ext) return true;
  159. if (!$this->fileSkip) return false;
  160. foreach ($this->fileSkip as $skip) {
  161. if (strpos($file, $skip) === 0) return true;
  162. }
  163. return false;
  164. }
  165. /**
  166. * 执行文件中行的跳过规则
  167. * @param string $string 行内容
  168. */
  169. private function skipLine($string) {
  170. if ($string == \'\') return true;
  171. foreach ($this->lineSkip as $tag) {
  172. if (strpos($string, $tag) === 0) return true;
  173. }
  174. return false;
  175. }
  176. }
复制代码






上一篇:discuz使用的php防止sql注入函数
下一篇:php短域名转换为实际域名函数
authicon fantuanzi 发表于 2011-6-18 01:00:04 | 显示全部楼层
支持一下,确实是不错的贴子。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1314学习网 ( 浙ICP备10214163号 )

GMT+8, 2025-5-3 04:12

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表