【问题标题】:Running preg_replace on html code taking too long在 html 代码上运行 preg_replace 耗时太长
【发布时间】:2014-06-10 11:45:36
【问题描述】:

冒着被重定向到this answer 的风险(是的,我读了它并花了最后 5 分钟大声笑),请允许我解释一下这个问题,这只是众多问题中的一个。

我的雇主要求我审查一个用 PHP 编写的网站,使用 Smarty 作为模板,使用 MySQL 作为 DBMS。它目前运行非常缓慢,最多需要 2 分钟(完全白屏,不少于)才能完全加载。

使用 xdebug 分析代码,我发现一个 preg_replace 调用大约需要 30 秒才能完成,该调用当前遍历所有 HTML 代码并将找到的每个 URL 替换为其 SEO 友好版本。完成后,它将所有代码输出到浏览器。 (正如我之前所说,这不是唯一的问题 - 代码相当旧,它显示了 - 但我将专注于这个问题。)

进一步深入研究代码,我发现它当前查看了 1702 个模式,每个匹配项都匹配(大小相等的数组中的匹配和替换),这肯定会考虑到它所花费的时间。

代码如下:

//This is just a call to a MySQL query which gets the relevant SEO-friendly URLs:   
$seourls_data = $oSeoShared->getSeourls();

$url_masks = array();
$seourls = array();
foreach ($seourls_data as $seourl_data)
{
    if ($seourl_data["url"])
    {
        $url_masks[] = "/([\"'\>\s]{1})".$site.str_replace("/", "\/", $seourl_data["url"])."([\#|\"'\s]{1})/";
        $seourls[] = "$1".MAINSITE_URL.$seourl_data["seourl"]."$2";
    }
}

//After filling both $url_masks and $seourls arrays, then the HTML is parsed:
$html_seo = preg_replace($url_masks, $seourls, $html);
//After it completes, $html_seo is simply echo'ed to the browser.

现在,我知道问题的明显答案是:不要使用正则表达式解析 HTML。但是,如何解决这个特定问题呢?我的第一次尝试可能是:

  1. 将(希望是格式良好的)HTML 加载到 DOMDocument 中,然后在每个 a 标签中获取每个 href 属性,like so.
  2. 遍历每个节点,替换为适当匹配找到的 URL(这可能意味着无论如何都要使用以前的正则表达式,但在一个大大减小的字符串上)
  3. ???
  4. 利润?

但我认为这很可能不是解决问题的正确方法。 有什么想法或建议吗?

谢谢。

【问题讨论】:

  • 我想说,不要把坏的 url 放在 html 开头,把好的。而不是这种非常缓慢的方式。
  • 目前,该网站无法使用。所以,我要做的第一件事是在数据库中创建一个新列,将过滤内容移至离线进程,并将结果记录在新列中。然后该网站至少可以工作,您可以着手修复实施。
  • that's not the only issue -the code is rather old, and it shows,到时候重写。不幸的是,没有快速的方法来做您想做的事,除非您修复内容中的 url,否则 regex-ing 1702 模式有点令人担忧。
  • 感谢所有 cmets(对于冗长的帖子感到抱歉,只是想我会尽可能清楚地说明。)是的,正在进行完整的网站重写(使用 Erlang/ChicagoBoss相反)但由于它不会很快准备好,所以旧网站暂时上线了。不幸的是,让网站处于工作状态太费力了,所以我的雇主告诉我不要管它。了解如何(不)编码的好机会,thougn。
  • 也许函数被优化了,你确定执行正则表达式所花费的时间吗?

标签: php html regex


【解决方案1】:

由于您的目标是对 SEO 友好,因此在目标页面中使用规范标签会告诉搜索引擎使用您的 SEO 友好 url,因此您无需在代码中替换它们...

【讨论】:

    【解决方案2】:

    糟糕,这真的很难,从一开始就是糟糕的策略,任何方式都不是你的错,
    我有 2 条建议:-
    1-通过 smarty 创建缓存技术,第一个 HTML 仍然在 2 分钟内生成 >
    第二个 HTML 只是从静态资源中获取。

    2-不要做以后必须做的事情,所以修复系统,创建一个数据库迁移,以良好的格式存储 SEO url 或使用标题或其他方式生成它,在我的系统上生成 SEO这种格式的链接..

    www.whatever.com/jobs/722/drupal-php-developer 我通过解析 url 来使用 722 作为 ID 来获取正确的页面内容,并且 (drupal-php-developer) 是帖子的标题或任何内容

    3 - (这不是建议)告诉您的客户项目设计不完善(如果您真的这么认为的话)并且需要重组以提高性能。 运行

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-01
      • 1970-01-01
      • 2018-06-29
      • 1970-01-01
      相关资源
      最近更新 更多