sparkle February 2016

Memory allocation problems while using a Stream through PHP

I'm using a stream in PHP by using the GuzzleHttp\Stream\Stream class. Whilst using it i'm getting PHP memory allocation problems. Is there a method i can use which doesn't use up much memory?

Problem

When i need to serve a Content-Range of 0-381855148 bytes (for example) this causes me a memory allocation issues. Is there a method how can i serve the content while not needing that much memory? Something that passes the data straight through, instead of "reserving" it in memory?

This is part of my code responsible for the error...

$stream = GuzzleHttp\Stream\Stream::factory(fopen($path, 'r'));
$stream->seek($offset);
while (!$stream->eof()) {
    echo $stream->read($length);
}
$stream->close();

This is passed as a callback function for my stream.

Background

First i tried fixing the problem by providing a maximum chunk length for my stream. I did this by giving my stream a maximum offset. It's fixes the memory allocation problem, but new problems arise in Firefox when distributing my dynamic video content. Chrome doesn't have problems with it.

It's because Firefox asks for a "0-" Content-Range but i give a Content-Range "0-" back. Instead i need to give back the whole range (until maximum) but this causes the infamous "Allowed memory size of 262144 bytes exhausted (tried to allocate 576 bytes)" error.

Disclaimer: it's actually a little bit more technical. But i wanted to keep it simple.

Does someone knows a solution? Thanks.

Answers


sparkle February 2016

Found my answer on a different forum.

The reason for the memory exhausted problem was because of Guzzle and the way it is build (PSR-7).

A more in in depth article about the problem: https://evertpot.com/psr-7-issues/

I fixed it using this code:

if ($i = ob_get_level()) {
    # Clear buffering:
    while ($i-- && ob_end_clean());
    if (!ob_get_level()) header('Content-Encoding: ');
}
ob_implicit_flush();

$fp = fopen($path, 'rb');
fseek($fp, $offset);
while ($length && !feof($fp)) {
    $chunk = min(8192, $length);
    echo fread($fp, $chunk);
    $length -= $chunk;
}
fclose($fp);

Credits goes to djmaze

Post Status

Asked in February 2016
Viewed 1,632 times
Voted 12
Answered 1 times

Search




Leave an answer