【问题标题】:PHP Return Long String is not Usable as StringPHP 返回长字符串不能用作字符串
【发布时间】:2019-07-11 01:04:39
【问题描述】:

我有一个循环遍历一个大数组$result。每个数组项$row 用于生成一个新的字符串行$line。这个字符串被连接成$str。为了保留内存,我使用unset($result[$i]) 来清除原始数组中已处理的每个数组项。这看起来像这样:

$resultcount = count($result);
for($i=0; $i<$resultcount; ++$i){
   $row = $result[$i];

   $line = do_something($row);
   $str.= '<tr><td>'.$line.'</td></tr>';
   unset($result[$i]);
}

return $str;

除非字符串的长度超过大约1'000'000 个字符。在这种情况下,返回值只是空的。这非常令人恼火,因为:

  1. 计算工作量(在本例中为do_something())不是问题。通过使用echo count($result).' - '.strlen($str)."\n",我可以看到循环正确完成。没有显示 Web 服务器或 php 错误。
  2. memory_limit 也不是问题。我正在处理应用程序其他部分的更多数据。

看来问题出在return $str 本身。如果我使用return substr($str, 0, 980000),那么它就可以正常工作。进一步调试表明,字符串一旦达到 999'775 字节的长度就会被污染。

我不能将更长的返回值字符串放入另一个字符串变量中。但我可以通过strlen() 获得正确的结果(1310307)。所以返回值字符串的总长度为 1'310'307 个字节。但是我不能正确地将它们用作字符串。

这个限制来自哪里,我该如何规避它?

【问题讨论】:

标签: php arrays string return return-value


【解决方案1】:

嗯,我花了两年半的时间才弄明白;(

Rarst 是对的:这不是函数编译和传递字符串的问题。在此过程的后期,我使用preg_replace() 进行了一些进一步的替换。此函数无法处理长字符串。如How to do preg_replace on a long string 中所述,这可以通过预先使用ini_set('pcre.backtrack_limit', 99999999999) 来解决

【讨论】:

    【解决方案2】:

    您似乎以自相矛盾的方式描述了返回值:

    在这种情况下,返回值只是空的。

    但是

    但我可以执行 strlen() 以获得正确的结果 (1310307)。所以返回值字符串的总长度为1'310'307字节。

    某事不能同时为空和有长度?

    我已经测试过返回一个这么长的字符串,它对我来说很好用。返回越来越大的字符串会超出内存限制,这会触发显式致命错误。

    在技术方面,字符串可能超过百万个字符:

    注意:从 PHP 7.0.0 开始,对于 64 位版本的字符串长度没有特别限制。在 32 位版本和早期版本中,字符串最大可达 2GB(最大 2147483647 字节) http://php.net/manual/en/language.types.string.php

    我怀疑失败的操作与您使用结果的方式有关,而不是从函数返回。

    【讨论】:

      猜你喜欢
      • 2015-04-07
      • 1970-01-01
      • 1970-01-01
      • 2015-09-18
      • 2011-12-04
      • 2010-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多