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


Posted in PHP onJanuary 17, 2011

<?php
/**
* @author xiaoxiao <x_824@sina.com> 2011-1-12
* @link http://xiaoyaoxia.cnblogs.com/
* @license
* 统计目录下的文件行数及总文件数··去除注释
*/

$obj = new CaculateFiles();
//如果设置为false,这不会显示每个文件的信息,否则显示
$obj->setShowFlag(false);
//会跳过所有All开头的文件
$obj->setFileSkip(array('All'));
$obj->run("D:\PHPAPP\php\_tests");

//所有文件,(默认格式为.php)
$obj->setFileSkip(array());
$obj->run("D:\PHPAPP\php");

$obj->setShowFlag(true);
//跳过所有I和A开头的文件,(比如接口和抽象类开头)
$obj->setFileSkip(array('I', 'A'));
$obj->run("D:\PHPAPP\php");

/**
* 执行目录中文件的统计(包括文件数及总行数
*
* 1、跳过文件的时候:
* 匹配的规则只是从文件名上着手,匹配的规则也仅限在开头。
* 2、跳过文件中的注释行:
* 匹配的规则只是从注释段落的头部匹配,如果出现// 及 *及 #及/*开头的行及空行会被跳过。所以类似/*这种多汗注释,每行的开头都必须加上*号,否则无法匹配到这种的注释。
* 3、目录过滤:
* 匹配的规则是从目录名的全名匹配
*/
class CaculateFiles {
/**
* 统计的后缀
*/
private $ext = ".php";
/**
* 是否显示每个文件的统计数
*/
private $showEveryFile = true;
/**
* 文件的的跳过规则
*/
private $fileSkip = array();
/**
* 统计的跳过行规则
*/
private $lineSkip = array("*", "/*", "//", "#");
/**
* 统计跳过的目录规则
*/
private $dirSkip = array(".", "..", '.svn');

public function __construct($ext = '', $dir = '', $showEveryFile = true, $dirSkip = array(), $lineSkip = array(), $fileSkip = array()) {
$this->setExt($ext);
$this->setDirSkip($dirSkip);
$this->setFileSkip($fileSkip);
$this->setLineSkip($lineSkip);
$this->setShowFlag($showEveryFile);
$this->run($dir);
}

public function setExt($ext) {
trim($ext) && $this->ext = strtolower(trim($ext));
}
public function setShowFlag($flag = true) {
$this->showEveryFile = $flag;
}
public function setDirSkip($dirSkip) {
$dirSkip && is_array($dirSkip) && $this->dirSkip = $dirSkip;
}
public function setFileSkip($fileSkip) {
$this->fileSkip = $fileSkip;
}
public function setLineSkip($lineSkip) {
$lineSkip && is_array($lineSkip) && $this->lineSkip = array_merge($this->lineSkip, $lineSkip);
}
/**
* 执行统计
* @param string $dir 统计的目录
*/
public function run($dir = '') {
if ($dir == '') return;
if (!is_dir($dir)) exit('Path error!');
$this->dump($dir, $this->readDir($dir));
}

/**
* 显示统计结果
* @param string $dir 目录
* @param array $result 统计结果(包含总行数,有效函数,总文件数
*/
private function dump($dir, $result) {
$totalLine = $result['totalLine'];
$lineNum = $result['lineNum'];
$fileNum = $result['fileNum'];
echo "*************************************************************\r\n<br/>";
echo $dir . ":\r\n<br/>";
echo "TotalLine: " . $totalLine . "\r\n<br/>";
echo "TotalLine with no comment and empty: " . $lineNum . "\r\n<br/>";
echo 'TotalFiles:' . $fileNum . "\r\n<br/>";
}

/**
* 读取目录
* @param string $dir 目录
*/
private function readDir($dir) {
$num = array('totalLine' => 0, 'lineNum' => 0, 'fileNum' => 0);
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
if ($this->skipDir($file)) continue;
if (is_dir($dir . '/' . $file)) {
$result = $this->readDir($dir . '/' . $file);
$num['totalLine'] += $result['totalLine'];
$num['lineNum'] += $result['lineNum'];
$num['fileNum'] += $result['fileNum'];
} else {
if ($this->skipFile($file)) continue;
list($num1, $num2) = $this->readfiles($dir . '/' . $file);
$num['totalLine'] += $num1;
$num['lineNum'] += $num2;
$num['fileNum']++;
}
}
closedir($dh);
} else {
echo 'open dir <' . $dir . '> error!' . "\r";
}
return $num;
}

/**
* 读取文件
* @param string $file 文件
*/
private function readfiles($file) {
$str = file($file);
$linenum = 0;
foreach ($str as $value) {
if ($this->skipLine(trim($value))) continue;
$linenum++;
}
$totalnum = count(file($file));
if (!$this->showEveryFile) return array($totalnum, $linenum);
echo $file . "\r\n";
echo 'TotalLine in the file:' . $totalnum . "\r\n";
echo 'TotalLine with no comment and empty in the file:' . $linenum . "\r\n";
return array($totalnum, $linenum);
}

/**
* 执行跳过的目录规则
* @param string $dir 目录名
*/
private function skipDir($dir) {
if (in_array($dir, $this->dirSkip)) return true;
return false;
}

/**
* 执行跳过的文件规则
* @param string $file 文件名
*/
private function skipFile($file) {
if (strtolower(strrchr($file, '.')) != $this->ext) return true;
if (!$this->fileSkip) return false;
foreach ($this->fileSkip as $skip) {
if (strpos($file, $skip) === 0) return true;
}
return false;
}

/**
* 执行文件中行的跳过规则
* @param string $string 行内容
*/
private function skipLine($string) {
if ($string == '') return true;
foreach ($this->lineSkip as $tag) {
if (strpos($string, $tag) === 0) return true;
}
return false;
}
}

PHP 相关文章推荐
PHP新手上路(七)
Oct 09 PHP
PHP下几种删除目录的方法总结
Aug 19 PHP
PHP foreach循环使用详解与实例代码
May 08 PHP
php中echo()和print()、require()和include()等易混淆函数的区别
Feb 22 PHP
php图片加中文水印实现代码分享
Oct 31 PHP
PHP 信号管理知识整理汇总
Feb 19 PHP
thinkPHP框架动态配置用法实例分析
Jun 14 PHP
PHP实现的敏感词过滤方法示例
Mar 06 PHP
PHP微信网页授权的配置文件操作分析
May 29 PHP
PHP创建XML接口示例
Jul 04 PHP
laravel csrf排除路由,禁止,关闭指定路由的例子
Oct 21 PHP
laravel 框架结合关联查询 when()用法分析
Nov 22 PHP
php短域名转换为实际域名函数
Jan 17 #PHP
PHP学习笔记之三 数据库基本操作
Jan 17 #PHP
PHP学习笔记之二
Jan 17 #PHP
PHP学习笔记之一
Jan 17 #PHP
php下连接mssql2005的代码
Jan 17 #PHP
Php Image Resize图片大小调整的函数代码
Jan 17 #PHP
php生成随机密码的几种方法
Jan 17 #PHP
You might like
短波的认识
2021/03/01 无线电
PHP中文分词 自动获取关键词介绍
2012/11/13 PHP
php 无法加载mcrypt.dll的解决办法
2013/04/03 PHP
2014年最新推荐的10款 PHP 开发框架
2014/08/01 PHP
thinkphp实现163、QQ邮箱收发邮件的方法
2015/12/18 PHP
深入剖析PHP中printf()函数格式化使用
2016/05/23 PHP
PHP实现生成推广海报的方法详解
2018/03/14 PHP
Gambit vs ForZe BO3 第一场 2.13
2021/03/10 DOTA
firebug的一个有趣现象介绍
2011/11/30 Javascript
javascript中typeof操作符和constucor属性检测
2015/02/26 Javascript
简介可以自动完成UI的AngularJS工具angular-smarty
2015/06/23 Javascript
仿百度换肤功能的简单实例代码
2016/07/11 Javascript
jQuery 检查某个元素在页面上是否存在实例代码
2016/10/27 Javascript
JS函数多个参数默认值指定方法分析
2016/11/28 Javascript
遍历json 对象的属性并且动态添加属性的实现
2016/12/02 Javascript
Angularjs 实现移动端在线测评效果(推荐)
2017/04/05 Javascript
Node使用Sequlize连接Mysql报错:Access denied for user ‘xxx’@‘localhost’
2018/01/03 Javascript
Vue服务端渲染实践之Web应用首屏耗时最优化方案
2019/03/22 Javascript
[01:14:05]《加油DOTA》第四期
2014/08/25 DOTA
[01:14]DOTA2 7.22版本新增神杖效果展示(智力英雄篇)
2019/05/29 DOTA
python 装饰器功能以及函数参数使用介绍
2012/01/27 Python
基于Python实现的扫雷游戏实例代码
2014/08/01 Python
python登录pop3邮件服务器接收邮件的方法
2015/04/30 Python
Python读取sqlite数据库文件的方法分析
2017/08/07 Python
pyqt5简介及安装方法介绍
2018/01/31 Python
Python爬虫 urllib2的使用方法详解
2019/09/23 Python
利用纯css3实现的文字亮光特效的代码演示
2014/11/27 HTML / CSS
CSS3绘制有活力的链接下划线
2016/07/14 HTML / CSS
使用html5新特性轻松监听任何App自带返回键的示例
2018/03/13 HTML / CSS
印度首选时尚目的地:Reliance Trends
2018/01/17 全球购物
校园文化艺术节宣传标语
2014/10/09 职场文书
2016年“5.12”国际护士节活动总结
2016/04/06 职场文书
Nginx部署vue项目和配置代理的问题解析
2021/08/04 Servers
《雀魂PONG☆》4月1日播出 PV角色设定情报
2022/03/20 日漫
Java 通过手写分布式雪花SnowFlake生成ID方法详解
2022/04/07 Java/Android
centos环境下nginx高可用集群的搭建指南
2022/07/23 Servers