PHP“Time Ago”时间转换函数计算长周期时导致服务器崩溃求助
问题原因
- 函数死循环的核心是数组长度不匹配:
$periods数组共8个单位(索引0-7),但对应的换算步长$lengths只有7个元素(索引0-6)。当时间差超过100年(即10个decade)时,循环变量$j会增加到7,此时读取$lengths[7]会得到null,PHP隐式转换后null等价于0,只要时间差为正数就永远满足$difference >= 0的循环条件,导致无限循环直到请求超时。 - 次要隐患:
$lengths里的数值都是字符串格式,隐式类型转换可能出现不可预期的计算错误。
修复方案
可按以下逻辑调整代码:
- 给循环增加边界判断,避免
$j超过$lengths的最大索引 - 将
$lengths的元素改为数值类型,规避隐式转换风险 - 若时间差超过最大单位(decade)的换算阈值,直接按最大单位计算即可
修复后代码
<?php function timeago($time) { if(!is_numeric($time)) $time = strtotime($time); if($time == 0) return 'never'; $periods = array("second", "minute", "hour", "day", "week", "month", "year", "decade"); // 步长改为数值类型,无需为最大单位decade设置后续换算规则 $lengths = array(60, 60, 24, 7, 4.35, 12, 10); $maxLengthIndex = count($lengths) - 1; $ending = "to go"; $difference = time() - $time; if($difference > 0) $ending = "ago"; else $difference = -$difference; // 增加循环边界判断,避免数组越界 for ($j = 0; $j <= $maxLengthIndex && $difference >= $lengths[$j]; $j++) { $difference /= $lengths[$j]; } $difference = round($difference); if($difference > 1) $periods[$j].= "s"; if($difference < 1) return 'just now'; return "$difference $periods[$j] $ending"; } ?>
内容的提问来源于stack exchange,提问作者John Matley
相关产品推荐
相关产品推荐

