沒有辦法按順序「讀取」已加載到內存中的字符串;分裂它並不是真的更高效。多個變量的開銷也會比單個變量更多地使用內存。理想情況下,您可以將字符串加載到流中,但PHP實際上並沒有字符串流。
如果你只是想以處理大塊的字符串,可以剛剛超過它的子循環:
$data;
$pointer = 0, $size = strlen($data);
$chunkSize = 1048576;
while ($pointer < $size)
{
$chunk = substr($data, $pointer, $chunkSize);
doSomethingWithChunk($chunk);
$pointer += $chunkSize;
}
我不知道PHP如何處理內部的大字符串,但根據string documentation,一個字符串只能「最大2GB(最大2147483647個字節)」。如果你的文件大約是10MB,那麼對PHP來說不應該是個問題。
另一個選項(可能是更好的選擇)是將$data
加載到memory or temporary stream。如果您想要避免內存過多,可以使用php://temp
流封裝器,其中一些數據存儲在臨時文件中(如果超過2MB)。只要儘快將字符串加載到流中以節省內存,然後就可以使用文件流功能。
$dataStream = fopen("php://temp", "w+b");
fwrite($dataStream, funcThatGetsData()); // try not to put data into a variable to save memory
while (!feof($dataStream))
{
$chunk = fread($dataStream, 1048576); // want to read 1MB at a time
doSomethingWithChunk($chunk);
}
fclose($dataStream);
如果從另一個功能得到$data
你可以繞過$dataStream
代替。如果你必須在一個字符串$data
事前,一定要打電話就可以了unset()
釋放內存:
$data = getData(); // string from some other function
$dataStream = fopen("php://temp", "w+b");
fwrite($dataStream, $data);
unset($data); // free 10MB of memory!
...
如果你想保持它所有的內存,你可以使用php://memory
,但是你可能也只是使用在這種情況下一個字符串。
這兩種方法都可以工作。不幸的是,我對兩種方法進行了基準測試,實際上它們比str_split慢*,所以我只是保持代碼的方式。 :)儘管謝謝你非常透徹的答案! 僅供參考,'php:// memory'的數量級比'str_split'慢了幾個數量級,而'substr'方法幾乎與w /'str_split'差不多。然而,'str_split'只是幾乎沒有更快 - 並且讀取/維護更容易。 最終結果:保持一切! – DOOManiac
@DOOManiac:我想到虛擬流會比較慢 - 使用'php:// temp'後面的想法是它有更高的內存效率。即使將它全部存儲在內存中,我敢打賭它使用的是原始C字節數組,而不是更方便但消耗更多內存的「$ string」。使用流和大塊閱讀功能可以防止你的記憶真的很高。如果這不是你的目標,那麼'str_split'可能是你最好的選擇。 ;) – coderstephen
我的目標是速度,純粹和簡單。儘管謝謝你的回答! – DOOManiac