Reputation: 338
I have a script that download's files from a server, all works nice. But when the file is downloaded either it's a jpg or png file. I cant seem to open it with any program to view it. (windows photo gallery or fireworks)
When i download a video file (avi). I cant open it with windows media player, but i can open it with vlc media player.
I always get a error msg, cant read file or file broken.
Here is the code, is it reliable or should i consider using fsocketopen or curl maybe.
I have tried altering the headers looking for more answers on the web, with no luck.
Anyone have an idea to whats wrong?
chmod("extensions_img/test.jpg",0755);
$fullPath = "http://www.website_url.com/extensions_img/test.jpg";
if ($fd = fopen ($fullPath, "r")) {
$fsize = filesize("extensions_img/test.jpg");
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
switch($ext) {
case "pdf":
$ctype = "application/pdf";
break;
case "exe":
$ctype = "application/octet-stream";
break;
case "zip":
$ctype = "application/zip";
break;
case "doc":
$ctype = "application/msword";
break;
case "xls":
$ctype = "application/vnd.ms-excel";
break;
case "ppt":
$ctype = "application/vnd.ms-powerpoint";
break;
case "gif":
$ctype = "image/gif";
break;
case "png":
$ctype = "image/png";
break;
case "jpeg":
$ctype = "image/jpg";
break;
case "jpg":
$ctype = "image/jpg";
break;
case "mp3":
$ctype = "audio/mp3";
break;
case "wav":
$ctype = "audio/x-wav";
break;
case "wma":
$ctype = "audio/x-wav";
break;
case "mpeg":
$ctype = "video/mpeg";
break;
case "mpg":
$ctype = "video/mpeg";
break;
case "mpe":
$ctype = "video/mpeg";
break;
case "mov":
$ctype = "video/quicktime";
break;
case "avi":
$ctype = "video/x-msvideo";
break;
case "src":
$ctype = "plain/text";
break;
default:
$ctype = "application/force-download";
}
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-type: " . $ctype);
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
header("Content-Transfer-Encoding: binary");
header("Content-length: $fsize");
header("Cache-control: public"); //use this to open files directly
while(!feof($fd)) {
$buffer = fread($fd, 4096);
flush();
}
}
fclose ($fd);
Upvotes: 1
Views: 11272
Reputation: 145482
Using filesize($url)
will download the file twice. And no idea why you are using fopen/fread
anyway, when there is file_get_contents
or fpassthru
:
$data = file_get_contents($url);
$size = strlen($data);
$mime = current(preg_grep('/^Content-Type:/i', $http_response_header));
Please note how this also gets you the correct MIME type (just pass along the whole stirng via header
for simplicity). Or even all the headers.
Upvotes: 0
Reputation: 4395
Try:
while(!feof($fd)) {
echo fread($fd, 4096);
flush();
}
You aren't echoing anything so probably your file is empty?
Upvotes: 1
Reputation: 270599
You are sending a Content-length:
header containing a filesize you obtained incorrectly.
// You are opening a remote file:
$fullPath = "http://www.website_url.com/extensions_img/test.jpg";
// You are retrieving the filesize of a local file that may or may not exist
$fsize = filesize("extensions_img/test.jpg");
So, most likely, your Content-length
really looks like the following:
header("Content-length: 0");
...unless you have an actual local file of the same name, then you'll be supplying its filesize rather than the intended remote file.
According to filesize()
documentation, some URL wrappers are supported. You might try to retrieve the filesize from the remote file:
As of PHP 5.0.0, this function can also be used with some URL wrappers. Refer to Supported Protocols and Wrappers to determine
which wrappers support stat() family of functionality.
$fsize = filesize($fullpath);
Upvotes: 0