本文目录导读:

- 场景一:统计研发工作量(Git + 代码提交)
- 场景二:统计员工工时(自定义任务系统)
- 场景三:统计用户行为工作量(埋点 + 日志)
- 场景四:统计代码本身量(静态分析)
- 场景五:复杂报表与可视化
- 选择适合你的方案
在PHP项目中实现工作量统计,通常涉及记录日志、监控行为、数据聚合和可视化展示,具体实现方式取决于你想统计什么(代码行数?任务工时?用户操作数?)以及项目的规模。
以下是几种常见的场景及其实现方案:
统计研发工作量(Git + 代码提交)
这是最常用的一种,统计开发者提交代码的频率、行数、影响文件数等。
基于Git日志(服务端脚本)
PHP可以通过exec()或shell_exec()执行Git命令,解析输出。
<?php
// 获取最近30天每位开发者的提交次数和行数变化
$since = date('Y-m-d', strtotime('-30 days'));
$until = date('Y-m-d');
// 统计每个人
$cmd = "git log --since={$since} --until={$until} --format='%aN' --shortstat --no-merges";
$output = shell_exec($cmd);
// 解析输出(简化示例)
$lines = explode("\n", $output);
$developers = [];
foreach ($lines as $line) {
if (preg_match('/^(\d+) file(s? changed)?, (\d+) insertion', $line, $matches)) {
$name = trim(array_pop($lines)); // 上一行是名字
$developers[$name]['commits']++;
$developers[$name]['insertions'] += $matches[3] ?? 0;
}
}
print_r($developers);
使用专业工具
- GitStats:生成HTML报表,包含时间线、活跃度。
- Gource:生成视频动画。
- 代码平台API(GitHub、GitLab、Gitee)都有贡献度API,可直接调用。
统计员工工时(自定义任务系统)
常用于外包团队或项目管理,统计每个人/每个任务花了多少小时。
核心表设计(MySQL)
-- 任务表
CREATE TABLE tasks (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
project_id INT NOT NULL,VARCHAR(255),
status ENUM('todo', 'doing', 'done') DEFAULT 'todo',
estimated_hours DECIMAL(5,1), -- 预估工时
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 工时记录表(关键)
CREATE TABLE time_logs (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
task_id INT NOT NULL,
start_time DATETIME NOT NULL,
end_time DATETIME,
duration_seconds INT DEFAULT 0, -- 实际秒数
note TEXT,
FOREIGN KEY (task_id) REFERENCES tasks(id)
);
PHP实现演示(Laravel风格)
// 1. 开始工作(点击“开始”按钮)
public function startTask($taskId) {
$log = new TimeLog();
$log->user_id = auth()->id();
$log->task_id = $taskId;
$log->start_time = now();
$log->save();
}
// 2. 结束工作(点击“结束”按钮)
public function stopTask($logId) {
$log = TimeLog::find($logId);
$log->end_time = now();
$log->duration_seconds = $log->end_time->diffInSeconds($log->start_time);
$log->save();
}
// 3. 统计某用户本月总工时
$userId = 1;
$totalSeconds = TimeLog::where('user_id', $userId)
->whereMonth('start_time', date('m'))
->whereYear('start_time', date('Y'))
->sum('duration_seconds');
echo '本月工时:' . round($totalSeconds / 3600, 2) . '小时';
前端辅助:使用JavaScript定时器自动记录活动时长(鼠标/键盘事件),定期发Ajax更新duration_seconds。
统计用户行为工作量(埋点 + 日志)
比如统计运营人员每天发帖数、客服处理工单数、管理员审核数。
方案:操作记录中间件
// 在核心控制器基类中注入
public function __construct() {
$this->middleware(function ($request, $next) {
$response = $next($request);
// 记录特定操作(如:审核通过、删除文章等)
if ($request->route()->named('admin.audit')) {
StatsRecorder::log([
'user_id' => auth()->id(),
'action' => 'audit',
'target_id' => $request->route('id'),
'ip' => $request->ip(),
'user_agent' => $request->userAgent(),
]);
}
return $response;
});
}
统计接口:
// 统计某用户某月的各类操作次数
$stats = DB::table('user_activity_log')
->select('action', DB::raw('count(*) as count'))
->where('user_id', $userId)
->whereBetween('created_at', [$startDate, $endDate])
->groupBy('action')
->get();
统计代码本身量(静态分析)
-
PHPLOC:非常流行的PHP代码统计工具,可统计代码行数、类数、方法数、复杂度等。
phploc src/
输出含
LLOC、CLOC、CCN(圈复杂度),可集成到CI/CD中。 -
自定义脚本:用PHP遍历目录,计算
.php文件行数。function countLines($dir) { $total = 0; $files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($dir) ); foreach ($files as $file) { if ($file->getExtension() === 'php') { $total += count(file($file->getPathname())); } } return $total; }
复杂报表与可视化
当数据量变大后,建议:
- 定时任务(Cron):每天凌晨汇总前一天的日志数据到统计表(
daily_work_summary),避免实时查询大量明细。 - 使用图表库:ECharts、Chart.js,后端返回JSON数据。
- 数据库优化:对
time_logs、activity_log按user_id、created_at建立复合索引。
高级技巧:缓存中间结果
// 使用Redis缓存昨天的日报(避免每天首次请求慢)
$dailyStats = Cache::remember('workload:user:'.$userId.':'.$date, 3600, function () use ($userId, $date) {
return DB::table('daily_summary')->where(['user_id' => $userId, 'date' => $date])->first();
});
选择适合你的方案
| 统计对象 | 推荐方案 | 工具/技术 |
|---|---|---|
| 开发者代码产出 | Git日志解析 + GitStats | shell_exec("git log…") |
| 员工工时 | 自定义Task + TimeLog表 | Laravel + MySQL |
| 用户操作量 | 中间件埋点 + 聚合统计 | 数据库 + 定时任务 |
| 代码规模/质量 | PHPLOC / PHP Depend | Composer包 |
| 全流程自动化统计 | 自建Dashboard + 图表 | ECharts + Redis |
最后建议:不要试图实时统计大量数据,对于生产环境,先记录原始日志,再通过定时任务或消息队列(如RabbitMQ)异步聚合到统计表,这样对主业务性能影响最小。