我的preg_match或get_file_contents是否会减慢我的页面?

时间:2018-06-19 10:59:09

标签: php regex

我的网站目前使用模板系统,该系统会加载.tpl个文件列表,并用正确的内容替换{bracelet},并在页面上输出。

我需要获取所有模板中所有手镯的列表,以便我可以阻止PHP运行特定于手镯的代码,这将有助于减少查询量。

目前我的页面加载时间为1.09秒,如果我添加以下代码,则页面加载时间会增加到1.53秒。

我收集这是因为我将100个左右的文件加载到内存中,然后加载到preg_match_all并将它们全部推入一个数组?

bracelets = [];

foreach($files as $file) {

    if (empty($file)) continue;

    $html = get_file_contents($file);


    $matches = [];

    preg_match_all("/{(.*?)\}/", $html, $matches);


    bracelets = (array_merge($bracelets, $matches[1]));
}

bracelets = array_unique(bracelets);

导致速度降低的代码是什么?

1 个答案:

答案 0 :(得分:1)

使用长度未知的文件时,基于懒点的模式可能会降低性能。如果在定界符之间出现大块文本(在这里为大括号),则会发生这种情况,因为{.*?}的工作方式如下:{被匹配,然后.*?被跳过,{{1}搜寻。如果不存在,则使用}来匹配.*?之后的字符,并测试下一个字符是否为{。在找到}之前,此过程重复的次数与}以外的其他字符相同。这意味着引擎仍然花费太多时间才能到达关闭定界符。

在使用}否定字符类时,您可以使用贪婪的[^}]*量词,因为您不再需要单独测试所有字符,因此引擎会贪婪地捕获所有1 /一次包含+以外的0个或更多字符,并达到}(如果有)。\

由于您需要匹配}之类的值并避免返回类似条目的{bracelet},因此您当前的正则表达式不仅速度慢,而且是错误的。

替换为

{brace let}

"/{([^{}\s]+)}/" 部分匹配[^{}\s]+{和空格以外的1个或多个字符。

关于串联仅保留唯一值的数组,请参见Fastest way to combine thousands of arrays uniquely in PHP