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

时间:2015-10-05 11:52:20

标签: php wordpress hhvm

我的服务器正在运行HHVM。

除了东西之外,一切都工作得很好。由于内存泄漏,翻译缓存会被填满,一旦它几乎已满,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中创建的函数调用?

1 个答案:

答案 0 :(得分:2)

基本上,要么手动编辑文件,要么编写一个替换所有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,然后匹配任何非(字符零次或多次(如果有空格)。然后匹配文字(,以及在正则表达式中未进一步定义的零个或多个字符(再次:这主要用于空格)
  • (\'([^\']+)\'|"([^"]+)"):既可以匹配单引号,也可以是单引号或双引号之间的任何内容,介于两者之间的任何内容都不是双引号。整个匹配被分组两次:一次用引号,一次没有引号。外观断言可以避免双重分组,但这只是我快速整理的一个正则表达式,如果你想要你可以做进一步的调整
  • \s*,\s*[\'"]:零个或多个空格,逗号和零个或多个空格,然后是单引号或双引号。这匹配传递给create_function的两个参数之间的逗号分隔符,我们不需要这个位,因此没有捕获
  • (.+?):匹配并捕获任何内容,直到模式的其余部分匹配
  • [\'"]\);$:单引号或双引号,右括号和EOL。简单地说:一行代码的最后3个可见字符。 ");来电的create_function字面值。也不需要捕获它,所以我们不

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

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

更多信息:

此正则表达式的regex101细分can be found here