preg_replace_callback 如果正则有问题,竟然不是返回原字符串,而是返回 null
WPJAM Basic 有个功能,就是在 WordPress 后台文章列表添加上文章特色图片,并且支持点击设置:

这个功能因为 WordPress 没有好的 Hook 使用,我是通过对最终生成的 HTML 实现正则替换实现的。
这个功能本来挺好的,然后有个用户说使用 WPJAM Basic 之后,说后台文章列表空白,经过我仔细的 Debug,原来他使用的标签太多了,使得 HTML 过于复杂,正则回溯次说过多,发生错误了。
原本我以为正则错就错了呗,最多就是正则替换不成功,功能没有,为啥还给我整成空白的呢?我仔细查了下 PHP 官方文档,原来 preg_replace_callback
函数的返回是这样的:
如果
subject
是一个数组, preg_replace_callback() 返回一个数组,其他情况返回字符串。错误发生时返回null
。
厄,错误发生时返回 null,第一次知道,一下子无言以对,原来之前正则都是成功了,我都没有去处理错误的情况,真的是。
然后 preg_replace
也是一样的情况,错误发生时返回 null。
所以我写了一个函数 wpjam_preg_replace
,同时实现 preg_replace_callback
和 preg_replace
的正则替换功能(它们的参数差不多,一个是回调,一个是替换的字符串),如果发生错误时,不是返回 null,而是返回原始 $subject
:
function wpjam_preg_replace($pattern, $replace, $subject, $limit=-1, &$count=null, $flags=0){
if(is_closure($replace)){
$result = preg_replace_callback($pattern, $replace, $subject, $limit, $count, $flags);
}else{
$result = preg_replace($pattern, $replace, $subject, $limit, $count);
}
if(is_null($result)){
trigger_error(preg_last_error_msg());
return $subject;
}
return $result;
}
如果发生了错误,并且在 log 中打印出具体的错误信息,方便查看原因,看看能不能优化正则什么的。这里有个限制,preg_replace_callback
的回调函数只能是闭包,因为同时要支持两个函数的原因,使用闭包比较容易判断。
有了这个函数之后,即使发生正则错误,至少还能显示页面,这也算是一种防御性编程(防御性编程是一种编程实践,旨在编写代码以抵御或处理潜在的错误和异常情况,以提高代码的健壮性和可靠性)。😆