vlucas / bulletphp

A resource-oriented micro PHP framework
http://bulletphp.com
BSD 3-Clause "New" or "Revised" License
416 stars 50 forks source link

Returning file content #55

Closed seblucas closed 6 years ago

seblucas commented 9 years ago

Hi,

Recently I had to return the content of a file for a specific path. This file is outside webspace so for now the only thing I could do was to read the file content and put it into response->content. Something like this :

$downloadFileName = $response->content()->getDownloadName();
$response->contentType($response->content()->getMimeType());
$data = file_get_contents($response->content()->getLocalPath());
$response->content($data);
$response->header("Content-Disposition", 'filename="' . $downloadFileName . '"');

My file are not that big so it's fine but I will have to use bigger files in the future so reading all the file content is not a good thing.

I'm willing to contribute this feature if you're interested in it and if you give me some pointers to avoid wasting too much time ;)

vlucas commented 9 years ago

It would be nice if we could build something into the Response object - something like $response->streamLocalFile('/some/path/here.csv', 'MyAwesomeExport.csv') that would handle all that stuff internally.

seblucas commented 9 years ago

Thanks for your input I'll try to do a PR soon

netom commented 6 years ago

The microscopic project https://github.com/netom/bullet-chunks does most of the work needed for this. One can create a chunked response object with a generator function that yields strings, and the response object will take care of the rest.

A simple fopen() - yield fread() - fclose() loop can serve a file of any size.

Be careful though. Just doing "echo $app->run()" is no good, since this calls __toString() on the resulting (chunked) response, which in turn reads the entire response data into memory.

One should instead call $app->run()->send(); instead. Fortunately the standard Bullet Request has this method too, so things will work as expected.