【问题标题】:php substr without memory consumpsionphp substr 不消耗内存
【发布时间】:2013-12-25 09:57:21
【问题描述】:

我需要将短字符串插入长字符串。我的问题是,字符串的 substr 成本内存......无论如何如何在不消耗新内存的情况下将长字符串分成两个。

 $str = "xxx...yyy"; // 10 MB

 $insert_str = "insert here";

 // now split long string and insert short string

 echo substr($str, 0, 5000000); // eats next 5 MB
 echo $insert_str;
 echo substr($str, 5000000); // eats next 5 MB

我的问题是脚本以致命错误结束:内存不足 但不会也不能为此添加额外的内存

我不能使用 substr_replace ... 因为什么都没有被替换... 是插入文本

我不能使用任何文件操作,因为文本是动态生成的(不在文件中)

【问题讨论】:

  • 请解释真正的问题,而不是你的“解决方案”。
  • 如果你在 PHP 中定义了一个 10 MB 的字符串,那么无论如何你都做错了。
  • 10 MB 字符串?该死,我的整个网站(仅计算 php、js 和 css 文件)的大小甚至不到 10 MB。

标签: php memory substr


【解决方案1】:

你可以试试substr-replace,但我不确定它的内存使用情况。 http://php.net/manual/en/function.substr-replace.php

编辑

Perl 更有效地处理字符串操作。将文件输出到服务器上的某个位置后,您需要执行脚本。

$perl = new Perl();
$perl->require("inserter.pl");

如果您使用 PHP,另一个好的解决方案是使用 preg_replace

【讨论】:

  • 那你回答的目的是什么?您是否认为 OP 无法阅读文档?
  • @zerkms 注意。我知道使用 perl 将是应用字符串操作的一种非常快速的方法。不过,它需要一个 exec 命令。我将进行编辑以使我的回答有价值。
  • “更有效地处理字符串操作” --- 没有意义,抱歉。
【解决方案2】:

可能是这样的:

$str = "xxx...yyy"; // 10 MB

$insert_str = "insert here";

// now split long string and insert short string

for($i=0;$i<5000000;$i++){
    echo $str[$i];
}
echo $insert_str;
$len = strlen($str);
for($i=5000000;$i<len;$i++){
    echo $str[$i];
}

【讨论】:

  • 非常慢...如果可以谈论 MB 意味着数百万个周期
【解决方案3】:

碰巧有人在 php 网站上发布了一个类似场景的示例。

$token_symbols = " \t\n";
$str = file_get_contents('10MB.txt'); // 9.75410079956 MB
tokenize($str, $token_symbols); // 9.75426483154 MB
unset($str);
strtok('', ''); // 0.0543975830078 MB


function tokenize($str, $token_symbols, $token_reset = true) {
    $word = strtok($str, $token_symbols);
    while (false !== $word) {
        // do something here...
        $word = strtok($token_symbols);
    }

    if($token_reset)
        strtok('', '');
}

以下是一个示例函数,它将在之后释放内存。

-- strtok() PHP manual

【讨论】:

  • 为什么不等待对应该解决的问题的真正解释而不是给出可能是愚蠢的问题的答案?
  • @zerkms 我尽量不认为任何问题都是愚蠢的,因为我不知道他为什么需要答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-12
  • 1970-01-01
相关资源
最近更新 更多