从WordPress到pcre.backtrack_limit

在WordPress里面写文章, 结果提交之后内容变成了空白. 完全不知道是什么原因, 第一个感觉是不是文章太长, 因为这篇文章粘贴了很长的代码. 但是即便如此, 对于MySQL,如果内容长度超过限制也应该是截断, 而不是空白. 而且post_content的类型是LONGTEXT, 绝对足够.

只能在WordPress的代码中排查, 主要是the_content filter上挂钩的函数, 逐个排查之后目光锁定在wpautop这个函数上, 再进一步, 锁定在如下语句上

    if (strpos($pee'<pre') !== false) {
        $pee = preg_replace_callback('!(<pre[^>]*>)(.*?)</pre>!is''clean_pre'$pee );
    }

函数的返回值是空值. 我的正文中有三个pre标签, 通过观察clean_pre的调用, 发现第三个pre根本没有匹配. Google的结果显示原因在于pcre.backtrack_limit. 这个值是正则表达式回溯的限制, 一旦超过就会出错. 新版本的PHP里面这个值是1000000, 而旧版本里面是100000, 100K, 很容易就超过了.

上面的非贪婪模式中每次匹配一个(.*?)中的字符都要检查一下后面跟随的是不是<pre>, 如果不是则返回继续匹配(.*?), 这样就是一次回溯, 显然里面的文本越多回溯次数就越多.

那么这个正则替换的作用是什么? 其实就是将pre标签里面的br 或者p标签去掉. 因为pre里面包含p或者br是不合规范的, 所以如果确定pre中不会包含这些标签, 完全可以不要做这个替换. 所以我的解决办法是将这行注释掉.

参考:pcre.backtrack_limit