PHP自定义异常:如何实现收集数据后的消息延迟格式化?
自定义PHP Exception实现延迟格式化错误消息
当前自定义Exception每次添加缺失数据时都会立即更新错误消息,存在不必要的重复计算。要实现仅在调用getMessage()时才动态生成最终错误消息的效果,可通过重写Exception类的getMessage()方法来实现,核心思路是将消息格式化逻辑延迟到方法调用时执行。
优化后的实现代码
class MissingAdjustmentDataException extends \Exception { private $missingRedemptionAdjustment = []; private $missingPlatformAdjustment = []; // 重写getMessage方法,延迟生成错误消息 public function getMessage(): string { $messageParts = ['Missing Adjustment data:']; // 处理RedemptionAdjustment缺失日期 if (!empty($this->missingRedemptionAdjustment)) { $formattedDates = array_map(function(\DateTime $date) { return $date->format('Y-m-d'); }, $this->missingRedemptionAdjustment); $messageParts[] = sprintf('RedemptionAdjustment: %s', implode(',', $formattedDates)); } // 处理PlatformAdjustment缺失日期(修复原代码循环错误) if (!empty($this->missingPlatformAdjustment)) { $formattedDates = array_map(function(\DateTime $date) { return $date->format('Y-m-d'); }, $this->missingPlatformAdjustment); $messageParts[] = sprintf('PlatformAdjustment: %s', implode(',', $formattedDates)); } // 无缺失数据时返回默认提示 if (count($messageParts) === 1) { return 'No missing adjustment data.'; } return implode(' ', $messageParts); } public function inError(): bool { return !empty($this->missingRedemptionAdjustment) || !empty($this->missingPlatformAdjustment); } public function addMissingRedemptionAdjustment(\DateTime $dateTime): void { $this->missingRedemptionAdjustment[] = clone $dateTime; // 移除原有的即时更新消息逻辑 } public function addMissingPlatformAdjustment(\DateTime $dateTime): void { $this->missingPlatformAdjustment[] = clone $dateTime; // 移除原有的即时更新消息逻辑 } }
关键优化点
- 移除了原
updateMessage方法,将消息生成逻辑移到重写的getMessage()中,仅在方法被调用时执行格式化 - 修复原代码bug:处理
PlatformAdjustment缺失数据时错误循环RedemptionAdjustment数组的问题 - 使用
array_map简化日期格式化代码,替代冗余的foreach循环 add*方法仅负责收集数据,不再触发消息计算,避免重复执行格式化逻辑- 动态拼接消息内容,无缺失数据时返回友好提示
使用方式(与原逻辑一致)
$missing = new MissingAdjustmentDataException(); $testDate = $period->getPreviousPeriod()->getEnd(); $z = 0; while ($testDate <= $period->getEnd() && $z < 500) { if (!in_array($testDate, array_column($activationRedemptionAdjustmentDays, 'effective'))) { $missing->addMissingRedemptionAdjustment($testDate); } if (!in_array($testDate, array_column($platformAdjustmentDays, 'effective'))) { $missing->addMissingPlatformAdjustment($testDate); } $testDate->add(new \DateInterval('P1D')); $z++; } // 仅当调用getMessage时才生成最终错误消息 if ($missing->inError()) { echo $missing->getMessage(); }
内容的提问来源于stack exchange,提问作者jdog
相关产品推荐
相关产品推荐

