Viewed   77 times

I want to serve an existing file to the browser in PHP. I've seen examples about image/jpeg but that function seems to save a file to disk and you have to create a right sized image object first (or I just don't understand it :))

In asp.net I do it by reading the file in a byte array and then call context.Response.BinaryWrite(bytearray), so I'm looking for something similar in PHP.

Michel

 Answers

1

There is fpassthru() that should do exactly what you need. See the manual entry to read about the following example:

<?php

// open the file in a binary mode
$name = './img/ok.png';
$fp = fopen($name, 'rb');

// send the right headers
header("Content-Type: image/png");
header("Content-Length: " . filesize($name));

// dump the picture and stop the script
fpassthru($fp);
exit;

?>

See here for all of PHP's filesystem functions.

If it's a binary file you want to offer for download, you probably also want to send the right headers so the "Save as.." dialog pops up. See the 1st answer to this question for a good example on what headers to send.

Wednesday, September 7, 2022
5

Here's what worked best for me when trying to script this (in case anyone else comes across this like I did):

$ pecl -d php_suffix=5.6 install <package>
$ pecl uninstall -r <package>

$ pecl -d php_suffix=7.0 install <package>
$ pecl uninstall -r <package>

$ pecl -d php_suffix=7.1 install <package>
$ pecl uninstall -r <package>

The -d php_suffix=<version> piece allows you to set config values at run time vs pre-setting them with pecl config-set. The uninstall -r bit does not actually uninstall it (from the docs):

vagrant@homestead:~$ pecl help uninstall
pecl uninstall [options] [channel/]<package> ...
Uninstalls one or more PEAR packages.  More than one package may be
specified at once.  Prefix with channel name to uninstall from a
channel not in your default channel (pecl.php.net)

Options:
  ...
  -r, --register-only
        do not remove files, only register the packages as not installed
  ...

The uninstall line is necessary otherwise installing it will remove any previously installed version, even if it was for a different PHP version (ex: Installing an extension for PHP 7.0 would remove the 5.6 version if the package was still registered as installed).

Monday, December 12, 2022
2

Just remove the output buffering (ob_start() and the others).

Use just this:

ftp_get($conn_id, "php://output", $file, FTP_BINARY);

Though if you want to add Content-Length header, you have to query file size first using ftp_size:

$conn_id = ftp_connect("ftp.example.com");
ftp_login($conn_id, "username", "password");
ftp_pasv($conn_id, true);

$file_path = "remote/path/file.zip";
$size = ftp_size($conn_id, $file_path);

header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=" . basename($file_path));
header("Content-Length: $size"); 

ftp_get($conn_id, "php://output", $file_path, FTP_BINARY);

(add error handling)


For more broad background, see:
List and download clicked file from FTP

Thursday, September 8, 2022
4

Never used any of those, but they look interesting..

Take a look at Gearman as well.. more overhead in systems like these but you get other cool stuff :) Guess it depends on your needs ..

Friday, November 11, 2022
 
4

Your implementation of move should use the rename function, which is atomic. Processes opening the file will see either the old or the new contents, there is no middle state. If a process already has opened the file it will keep having access to the old version after move.

Monday, August 1, 2022
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :