如何修复 Wordpress 中的内存泄漏?
How to Fix memory leak in Wordpress?
我的服务器是 运行 HHVM。
一切正常,除了 thing。由于内存泄漏,翻译缓存被填满,一旦它快满了,HHVM 就无法再呈现页面,因此每个用户只会看到一个空白页面,而不是文章。
为了防止这种情况发生,有必要将所有 create_function
调用替换为匿名函数。
请参阅(了解更多信息):
https://github.com/facebook/hhvm/issues/4250#issuecomment-88941383
和 hhvm 的文档也说要使用匿名函数:
所以我现在的问题是如何用匿名函数替换在 translation.php
和 po.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
我的服务器是 运行 HHVM。
一切正常,除了 thing。由于内存泄漏,翻译缓存被填满,一旦它快满了,HHVM 就无法再呈现页面,因此每个用户只会看到一个空白页面,而不是文章。
为了防止这种情况发生,有必要将所有 create_function
调用替换为匿名函数。
请参阅(了解更多信息):
https://github.com/facebook/hhvm/issues/4250#issuecomment-88941383
和 hhvm 的文档也说要使用匿名函数:
所以我现在的问题是如何用匿名函数替换在 translation.php
和 po.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