PHP项目如何实现工作量统计?

wen PHP项目 1

本文目录导读:

PHP项目如何实现工作量统计?

  1. 场景一:统计研发工作量(Git + 代码提交)
  2. 场景二:统计员工工时(自定义任务系统)
  3. 场景三:统计用户行为工作量(埋点 + 日志)
  4. 场景四:统计代码本身量(静态分析)
  5. 场景五:复杂报表与可视化
  6. 选择适合你的方案

在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/

    输出含 LLOCCLOCCCN(圈复杂度),可集成到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;
    }

复杂报表与可视化

当数据量变大后,建议:

  1. 定时任务(Cron):每天凌晨汇总前一天的日志数据到统计表(daily_work_summary),避免实时查询大量明细。
  2. 使用图表库:ECharts、Chart.js,后端返回JSON数据。
  3. 数据库优化:对time_logsactivity_loguser_idcreated_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)异步聚合到统计表,这样对主业务性能影响最小。

抱歉,评论功能暂时关闭!