PHP中可否同时使用||和&&?逻辑判断导致日志邮件重复发送排查
问题定位与修复方案
核心错误1:运算符优先级导致逻辑判断完全错误
PHP中&&的优先级高于||,你原有判断条件:
if (!$lastRun || filectime($log) < strtotime($lastRun) && $this->checkIfAlreadyExists($content) === false) { continue; }
实际执行顺序为:
if (!$lastRun || (filectime($log) < strtotime($lastRun) && $this->checkIfAlreadyExists($content) === false)) { continue; }
和你预期的逻辑完全不符:当已经有上次运行记录时,只有「文件时间早于上次运行+日志不含指定文本」两个条件同时满足才会跳过,只要日志含指定文本,哪怕已经处理过也不会跳过,直接加入发送列表,就会导致重复发送。你删掉&&之后的部分后,条件变成只要有上次运行记录且文件时间早于上次运行就跳过,自然就不会重复发送了,和你遇到的现象完全吻合。
核心错误2:判断逻辑写反
你预期的跳过规则是:只要满足以下任意一个条件就跳过该文件,不加入发送列表
- 日志中不存在你要检测的指定文本
- 不是第一次运行,且文件修改时间早于上次运行时间(已处理过)
原条件完全写反了判断规则,导致已经处理过的符合文本要求的文件不会被过滤。
其他次要错误
fclose参数错误:你fopen返回的文件句柄是$open,但你写了fclose($log),$log是文件名字符串,会导致资源泄漏- 使用
filectime不准确:ctime是文件inode修改时间,判断文件内容是否更新应该用filemtime(文件内容修改时间) $logs变量未初始化:直接在循环里写$logs[]会报Undefined variable警告- 正则匹配没必要用
preg_match_all:只要判断指定文本是否存在,用preg_match即可,性能更好
修复后完整代码
public function start() { $pattern = $this->config["twp_pattern"] ?? '*.log'; $pathLog = (isset($this->config["twp_path"])) ? trim($this->config["twp_path"], '/') : 'var/log'; $lastRun = (isset($this->config['twp_last_run'])) ? str_replace('T', ' ', $this->config['twp_last_run']) : false; $path = getcwd() . '/' . $pathLog . '/' . $pattern; $this->now = new \DateTime(); // 初始化日志数组 $logs = []; foreach (glob($path) as $log) { $open = fopen($log, 'r') or die ('File opening failed'); $content = fread($open, filesize($log)); var_dump($content); // 修正fclose参数 fclose($open); // 修正逻辑:只要不含指定文本,或者已经处理过的文件,直接跳过 if ( $this->checkIfAlreadyExists($content) === false || ($lastRun && filemtime($log) < strtotime($lastRun)) ) { continue; } $logs[] = $log; } $success = true; if (!empty($logs)) { $success = $this->sendMail($logs); } if($success === false){ return false; } $this->setLastRun(); return true; } public function checkIfAlreadyExists($content){ // 改用preg_match,只要匹配到一次就返回真 if (!preg_match('/already exists/', $content)) { echo "is not there"; return false; }else{ echo "is there"; return true; } }
内容的提问来源于stack exchange,提问作者Zyfella
相关产品推荐
相关产品推荐

