PHP脚本统计电信日志中未接与已完成通话数的技术求助
解决电信日志中未接/已完成通话统计的PHP方案
嘿,我之前也折腾过类似的电信日志报表脚本,这种分状态统计确实容易卡壳——毕竟不同运营商的日志格式差异还挺大的。不过从你已经用「Start」统计总通话数的思路来看,咱们可以顺着这个逻辑延伸,核心是找到未接通话和已完成通话的特征标识。
先明确日志的核心特征
首先得确认你的日志结构,通常电信日志有两种常见格式:
- 单条通话跨多行记录:每行对应通话的一个阶段(比如
Start→Connected→End,或者Start→Missed) - 单条通话单记录:一行包含完整的通话状态(比如
[2024-05-20 10:00:00] Start | Status: Missed | From: 13xxxxxxxxx)
下面针对这两种场景给你具体的实现代码:
场景1:单条通话跨多行记录
如果你的日志是按通话阶段分行的,比如一条未接通话只有Start没有End,或者有明确的Missed标记,那可以用状态追踪的方式统计:
<?php $logPath = 'telecom_center_logs.txt'; // 读取日志,忽略空行和换行符 $logLines = file($logPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $totalCalls = 0; $completedCalls = 0; $missedCalls = 0; $isActiveCall = false; // 标记当前是否处于一条未结束的通话中 foreach ($logLines as $line) { // 检测通话开始 if (str_contains($line, 'Start')) { $totalCalls++; $isActiveCall = true; } // 检测通话正常结束(已完成) elseif (str_contains($line, 'End') && $isActiveCall) { $completedCalls++; $isActiveCall = false; } // 检测未接通话标记(比如Missed/NO_ANSWER等,根据你的日志调整) elseif (str_contains($line, 'Missed') && $isActiveCall) { $missedCalls++; $isActiveCall = false; } } // 处理日志截断的情况:只有Start没有结束标记的通话,算作未接 if ($isActiveCall) { $missedCalls++; } // 输出结果 echo "总通话数:{$totalCalls}\n"; echo "已完成通话数:{$completedCalls}\n"; echo "未接通话数:{$missedCalls}\n"; ?>
场景2:单条通话单记录
如果每条通话是一行完整记录,包含状态字段,那直接匹配关键词即可:
<?php $logPath = 'telecom_center_logs.txt'; $logLines = file($logPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $totalCalls = 0; $missedCalls = 0; foreach ($logLines as $line) { // 先统计总通话数(匹配Start) if (str_contains($line, 'Start')) { $totalCalls++; // 同时检测是否是未接通话(根据你的日志状态字段调整,比如Status: Missed) if (str_contains($line, 'Status: Missed')) { $missedCalls++; } } } // 已完成通话数 = 总通话数 - 未接通话数 $completedCalls = $totalCalls - $missedCalls; echo "总通话数:{$totalCalls}\n"; echo "已完成通话数:{$completedCalls}\n"; echo "未接通话数:{$missedCalls}\n"; ?>
关键注意事项
- 调整关键词:不同电信中心的日志标记可能不一样,比如未接可能用
NO_ANSWER、Unanswered,已完成可能用Connected、Completed,你可以先打印几条日志行,确认准确的关键词。 - 日志编码:如果日志是GBK等非UTF-8编码,记得用
file_get_contents配合mb_convert_encoding转码后再处理,避免乱码导致匹配失败。 - 大日志优化:如果日志文件特别大,不要一次性用
file()读取全部内容,改用fopen逐行读取,减少内存占用。
内容的提问来源于stack exchange,提问作者AlanKelvin
相关产品推荐
相关产品推荐

