【问题标题】:PHP strpos and substr functions causes 'Allowed memory size exhausted' errorPHP strpos 和 substr 函数导致“允许的内存大小耗尽”错误
【发布时间】:2014-02-15 11:40:42
【问题描述】:

我的代码部分如下:

while( $pos1 = stripos( $description, '<style' ) ) {
  $pos2 = stripos( $description, '</style>' ) + 8;
  $description = substr( $description, 0, $pos1 ).
                 substr( $description, $pos2 );     //   <= This string causing the error
}

有时(不是一直!)我收到错误:

致命错误:第 88 行 /path/to/my/script.php 中允许的内存大小为 268435456 字节已用尽(尝试分配 107663188 字节)

上面的“

$description 变量的大小约为 100 kB。此外,我没有任何理由相信这段代码会导致内存分配的积累而不被释放。

你发现我的代码有什么缺陷吗?

【问题讨论】:

  • 如果您的 $description 大小为 100k,那么您基本上是在创建两个总大小略低于 100k 的子字符串,并且将它们连接起来需要另外 100k 左右......那是 300k,加上$description 的原始 100k 大小....您正在使用近 400k 的内存来执行该行代码
  • 如果您正在处理 HTML 标记,请尝试使用 DOM
  • 如果找不到&lt;/style&gt;怎么办? $pos2 将返回 FALSE,它将被转换为 0 并且您的子字符串不断增长。
  • @Bart - 如果没有找到&lt;style&gt;,它将不会执行while循环中的代码
  • 每次迭代将释放 300k 的内存,一旦完成,您显示的代码中没有先前循环的积累

标签: php memory-leaks substr strpos


【解决方案1】:

看起来问题是因为如果找不到&lt;/stile&gt; - $description 变量将增长到无穷大。 如果在 &lt;script ... /&gt; 表单中使用了 &lt;script&gt; 标记,则会出现这种情况 现在代码如下:

while( $pos1 = stripos( $description, '<style' ) ) {
  $pos2 = stripos( $description, '</style' ) + 8;
  if( $pos2 < $pos1 ) $pos2 = strpos( $description, '/>' ) + 2;
  if( $pos2 < $pos1 ) break 2;
  $description = substr( $description, 0, $pos1 ).
                 substr( $description, $pos2 );
}

看起来没有错误了...

【讨论】:

    【解决方案2】:

    此代码导致内存错误

    $description = 'hello<style></style>hello<style>';
    while( $pos1 = stripos( $description, '<style' ) ) {
        $pos2 = stripos( $description, '</style>' ) + 8;
        $description = substr( $description, 0, $pos1 ).
            substr( $description, $pos2 );     //   <= This string causing the error
    }
    

    【讨论】:

      猜你喜欢
      • 2017-12-13
      • 2011-07-12
      • 1970-01-01
      • 1970-01-01
      • 2013-10-21
      • 1970-01-01
      • 1970-01-01
      • 2020-11-20
      • 2015-05-30
      相关资源
      最近更新 更多