如何修复 Wordpress 中的内存泄漏?

How to Fix memory leak in Wordpress?

我的服务器是 运行 HHVM。

一切正常,除了 thing。由于内存泄漏,翻译缓存被填满,一旦它快满了,HHVM 就无法再呈现页面,因此每个用户只会看到一个空白页面,而不是文章。

为了防止这种情况发生,有必要将所有 create_function 调用替换为匿名函数。 请参阅(了解更多信息):

https://github.com/facebook/hhvm/issues/4250#issuecomment-88941383

和 hhvm 的文档也说要使用匿名函数:

http://docs.hhvm.com/manual/en/function.create-function.php

所以我现在的问题是如何用匿名函数替换在 translation.phppo.php 中进行的创建函数调用?

基本上,要么手动编辑文件,要么编写一个脚本来替换所有 create_function 调用并将它们变成闭包。像这样的东西应该足以完成这项工作:

$string = file_get_contents('path/to/po.php');


if (preg_match_all('/($.+?)create_function[^\(]*\(.*?(\'([^\']+)\'|"([^"]+)")\s*,\s*[\'"](.+?)[\'"]\);$/m', $string, $matches)) {
    $createCalls = count($matches[0]);
    $createStrings = [];//array of matches
    $replaceStrings = [];//array of new bits of code
    for ($i=0;$i<$createCalls;++$i) {
        //iterate over matches, build replace strings
        $createStrings[] = $matches[0][$i];//the full match
        $args = $matches[3][$i] ?: $matches[4][$i];//I'll explain this later on
        $replaceStrings[] = sprintf(
            '%sfunction(%s) {' . PHP_EOL . '    %s' . PHP_EOL . '};',
            $matches[1][$i],
            $args,
            $matches[5][$i]
        );
    }
    $string = str_replace($createStrings, $replaceStrings, $string);
    file_put_contents('path/to/po.php', $string);//write new contents to file
}

只是为了证明它有效 Demo here

在正则表达式上:

  • ($.+?):匹配并捕获赋值:文字$符号,后跟任意字符,非贪婪,因为?。当模式的下一部分匹配时,匹配将停止
  • create_function[^\(]*\(.*?:按字面意思匹配 create_function,然后匹配任何非 ( 字符零次或多次(如果有 space)。然后匹配文字 ( 和零个或多个未在正则表达式中进一步定义的字符(同样:这主要用于 spaces)
  • (\'([^\']+)\'|"([^"]+)"):要么匹配单引号,要么匹配单引号,要么匹配双引号,要么匹配双引号。整个匹配被分组两次:一次有引号,一次没有引号。环视断言本可以避免双重分组,但这只是我快速组合的正则表达式,如果需要,可以进一步调整它
  • \s*,\s*[\'"]:零个或多个 space,逗号和零个或多个 space,后跟单引号或双引号。这匹配传递给 create_function 的两个参数之间的逗号分隔符,我们不需要这个位,因此没有捕获
  • (.+?):匹配并捕获任何内容,直到模式的其余部分匹配
  • [\'"]\);$:单引号或双引号,右括号一个分号和一个 EOL。简单地说:单行代码的最后 3 个可见字符。 create_function 调用的结束 "); 文字。也不需要捕获这个,所以我们不

现在我们知道我们的 $matches 数组会是什么样子了:

  • 0:整行$var = create_function('$arg1', 'return $arg1;');
  • 1$var =位(实际赋值)
  • 2:第一个参数,带引号:'$arg1'
  • 3:第一个参数,不带引号:$arg1如果参数使用单引号分隔,如果使用双引号则为空字符串被使用
  • 4:第一个参数,如果使用双引号分隔,如果使用单引号
  • 则为空字符串
  • 5:不带引号的第二个参数,即:函数体

更多信息:

regex101 breakdown of this regex can be found here