统计应优先由数据库完成,如用PDO执行带GROUP BY的SQL;文件数据量大时需转数据库处理;实时计数须用原子操作或Redis;前端展示前须校验、格式化数据。

统计前先确认数据源是否可聚合
PHP 本身不直接“统计”,它只是从数据库或文件里取数、加工、输出。关键在 SELECT COUNT(*)、SUM()、GROUP BY 这些 SQL 是否写对。如果用的是 MySQL,别直接 mysql_query()(已废弃),必须用 PDO 或 mysqli;如果数据来自 CSV 或 JSON 文件,得先 file_get_contents() + json_decode() 或 fgetcsv(),再用 array_reduce() 等 PHP 函数算——但量大时会卡死,10 万行以上建议扔给数据库。
用 PDO 执行带 GROUP BY 的统计查询最稳妥
常见需求如“每天注册用户数”“各状态订单量”,直接让数据库算比 PHP 循环快得多。注意绑定参数防注入,别拼接字符串:
$pdo = new PDO('mysql:host=localhost;dbname=app', $user, $pass);
$stmt = $pdo->prepare("SELECT DATE(created_at) as day, COUNT(*) as cnt FROM users WHERE created_at >= ? GROUP BY day ORDER BY day");
$stmt->execute(['2024-01-01']);
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
-
DATE(created_at)把时间转成日期,避免按秒分组 - WHERE 条件一定要有,否则全表扫描,页面卡住是常态
- 如果字段含 NULL,
COUNT(col)会忽略它,COUNT(*)不会——选错就少算
实时统计要防并发重复计数
比如“今日访问量”这种需要每次请求都 +1 的场景,别用 SELECT + UPDATE 两步走,中间可能被其他请求插队。正确做法是单条原子语句:
$pdo->exec("INSERT INTO stats (day, pv) VALUES ('2024-04-05', 1) ON DUPLICATE KEY UPDATE pv = pv + 1");
- 表必须有
UNIQUE(day)索引,否则ON DUPLICATE KEY不生效 - 如果用 Redis,直接
$redis->incr('pv:2024-04-05')更轻量,但得额外维护过期逻辑 - 别在 PHP 里读出来、加 1、再写回去——高并发下大概率丢数
前端展示前记得做基础校验和格式化
统计结果常要转成图表,但原始数据可能有空值、负数、超大数。直接 echo json_encode($data) 给 JS 用容易出错:
立即学习“PHP免费学习笔记(深入)”;
- 用
is_numeric()检查cnt字段,防止 SQL 注入残留或字段类型错乱 - 大数字用
number_format($val, 0, '', ',')加千分位,不然 1000000 看着费劲 - 日期字段如果是
Y-m-d字符串,前端 new Date() 可能解析失败,建议统一转为时间戳:strtotime($row['day'])
统计逻辑越简单越好,复杂计算尽量推给数据库或专用服务;真正难的不是写代码,而是搞清“这个数到底该从哪来、谁负责更新、什么时候失效”。



















