How to solve the issue with downloading in PHP? - php

guys.
I am using a local server with laravel framework and trying to download file.
I tried many cases but nothing works for me.
The thing is I get no errors.
Downloading wont`t start but in response I have something like this:
�
���JFIF��;CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 95��C
���}!1AQa"q2���#B��R��$3br�
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz���������������������������������������������������������������������������
���w!1AQaq"2�B���� #3R�br�
$4�%�&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz��������������������������������������������������������������������������?���!�A���I��+�P�sB���i��?�Y�L��iG���B���Ap�����J;���;}ic=F{R�Z��
�$��z�q��~�p8�h�v?A#��;����t�#�Fx��Ǯq�S#<������qS-
That what I used:
tried this way:
$file = 'D:\Server\OpenServer\domains\memo.ru\public\img\avatars\\'.$file_name;
$filePath=$file;
and this:
$file = "http://example.com/img/avatars/1457091259.png";
1.
set_time_limit(0);
$file = #fopen($filePath, 'rb');
while ( !feof($file) ) {
print( #fread($file,1024*8) );
//ob_flush();
flush();
}
2
$handle = fopen($filePath, 'rb');
$buffer = '';
while ( !feof($handle) ) {
$buffer = fread($handle, 4096);
echo $buffer;
ob_flush();
flush();
}
fclose($handle);
3
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
//header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
4
$real_path = 'D:\Server\OpenServer\domains\example.com\public\img\avatars\\';
$file = "http://example.com/img/avatars/1457091259.png";
$url = 'http://example.com/img/avatars/'.$tmpFileName;
$path = $real_path.$tmpFileName;
$fp = fopen($path, 'w');
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FILE, $fp);
$data = curl_exec($ch);
curl_close($ch);
fclose($fp);

If you're using Laravel 5 then this would be the most straightforward way:
public function download()
{
$file = base_path(). "public/img/avatars/1457091259.png";
$name = "Human Name For File.jpg";
$headers = ['Content-Type: application/octet-stream'];
return Response::download($file, $name, $headers);
}
Just name sure you have use Response at the top before the class
The application/octet-stream header should force the browser to download the file rather than display it in the browser window.

This should work
header('Content-Type: image/png');
header('Content-disposition: attachment; filename='.$fileName);
echo readfile($file);
die();

I have used the following quite successfully for downloading / sending files - perhaps it will be of use to you?
Call it like:
call_user_func( 'send_file', 'myfile.docx', 'c:/temp/document.docx' );
function send_file( $name, $strPath ) {
if( file_exists( $strPath ) ) {
if( !is_file( $strPath ) or connection_status()!=0 ) { return FALSE; }
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Expires: ".gmdate("D, d M Y H:i:s", mktime(date("H")+2, date("i"), date("s"), date("m"), date("d"), date("Y")))." GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Content-Type: application/octet-stream");
header("Content-Length: ".(string)( filesize( $strPath ) ) );
header("Content-Disposition: inline; filename={$name}");
header("Content-Transfer-Encoding: binary\n");
if( $file = fopen( $strPath, 'rb' ) ) {
while( !feof( $file ) and ( connection_status()==0 ) ) {
print( fread( $file, 1024*8 ) );
flush();
}
fclose( $file );
}
clearstatcache();
return( ( connection_status()==0 ) and !connection_aborted() );
}
}

Related

How to download zip with php without messy code

I want to download xxx.zip in my linux server.
And I got the code from php offical web site. The url is
http://php.net/manual/en/function.readfile.php
I have set content-Type: application/zip. But unlucky, when executing the download.php, I got messy code in firfox or chrome browser.
My linux charset and browser charset are both utf-8.
Here is my download.php code:
<?php
$file_name = "xxx.zip";
if (!file_exists ($file_name)){
echo "file is not exist";
exit();
}
else{
header('Content-Description: File Transfer');
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="'.basename($file_name).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file_name));
readfile ($file_name);
exit;
}
?>
Compress xxx.zip code is:
<?php
$fileArr={1.jpg,2.jpg,3.jpg};
$fpName="xxx.zip";
$zip=new ZipArchive();
$zip->open($fpName,ZipArchive::CREATE);
foreach($fileArr as $file)
{
$zip->addFile("files/".$file,basename($file));
//$zip->renameName($file,$fileChName);
}
$zip->close();
?>
However, I can download xxx.zip file with xftp from linux server, and decompressing xxx.zip successfully in my windows desktop.
$file_name = "xxx.zip";
header("Cache-Control: no-cache, must-revalidate");
header("Expires: 0");
header("Content-Disposition: attachment; filename=\"" .basename($file_name)."\"");
header("Content-Length: " . filesize($file_name));
header("Content-Type: application/zip;");
readfile($file_name);
exit;
This will work.
A function I have used several times to download files might be of use
function sendfile( $filename=null, $filepath=null ){
if( file_exists( $filepath ) ){
if( !is_file( $filepath ) or connection_status()!=0 ) return false;
header("cache-control: no-store, no-cache, must-revalidate");
header("pragma: no-cache");
header("expires: ".gmdate("d, d m y h:i:s", mktime( date("h")+2, date("i"), date("s"), date("m"), date("d"), date("y")))." gmt");
header("content-type: application/octet-stream");
header("content-length: ".(string)( filesize( $filepath ) ) );
header("content-disposition: inline; filename={$filename}");
header("content-transfer-encoding: binary\n");
if( $file = #fopen( $filepath, 'rb' ) ) {
while( !#feof( $file ) and ( connection_status()==0 ) ) {
print( fread( $file, 1024*8 ) );
flush();
}
#fclose( $file );
}
return( ( connection_status()==0 ) and !connection_aborted() );
}
}
$file_name = "xxx.zip";
if( file_exists( $file_name ) ) sendfile( 'somefile.zip', $file_name );

PHP File Down with header()

I have written the following code to allow download of files without the source being displayed.
In this example, the file 'test.pdf' is downloaded, but its corrupt.
Can anyone see any reason this would be the case?
$path = 'http://www.domain.org/images/uploads/test.pdf';
// Directory Path
$directory_path_filename = str_replace('http://www.domain.org/', '', $path);
$filepath = '/var/sites/l/domain.org/public_html/'.$directory_path_filename;
if ( file_exists( $filepath ) ) {
$finfo = finfo_open( FILEINFO_MIME );
header( 'Content-Type: application/pdf' );
header( 'Content-Disposition: attachment; filename= ' . basename( $filepath ) );
header( 'Content-Length: ' . filesize( $filepath ) );
header( 'Expires: 0' );
finfo_close( $finfo );
ob_clean( );
flush( );
readfile( $filepath );
exit;
}
Please use this method
$file receive the full path, $filename is the download filename.
public static function downloadFile($file, $filename)
{
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename = '.basename($filename));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check = 0, pre-check = 0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
die;
}
}

PHP File Download code runs but outputs notthing on my local host

foreach ($idsonly as $key=>$price) {
if($curencyarray[$key]=="Internet Download"){
$dfr = $productidarray[$key].'.'.$itemformatarray[$key];
$file = 'C:wamp/www/allcars/Dhotois/'.$bigidarray[$key].'/'.$dfr;
$fie = str_replace("; charset=binary","",$mimeformarray[$key]);
$filename = $dfr;
$filepath = "C:wamp/www/allcars/Dhotois/".$bigidarray[$key]."/" . $filename;
set_time_limit(0);
ignore_user_abort(false);
ini_set('output_buffering', 0);
ini_set('zlib.output_compression', 0);
header("Content-Description: File Transfer");
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: ".$fie."");
header("Content-Disposition: attachment; filename=\"".basename($filepath)."");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".#filesize($filepath));
set_time_limit(0);
#readfile("$filepath") or die("File not found.");
ob_clean();
}
}
The above block of code runs but does not display the download box, the file i am trying to download is a jpeg file, i already set ob_start(); at the top of the page and if i remove the ob_clean(); from the code, it shows me this gibberish below
0041430000c945000015480000887a0000b3ca000094cf0000e1d6000011de0000a9860100��ICC_PROFILElcmsmntrRGB XYZ �)9acspAPPL���-lcms desc�^cprt\wtpthbkpt|rXYZ�gXYZ�bXYZ�rTRC�#gTRC�#bTRC�#descc2textFBXYZ ���-XYZ 3�XYZ o�8��XYZ b����XYZ $����curv��c�k�?Q4!�)�2;�FQw]�kpz���|�i�}���0����C "##! %*5-%'2( .?/279<<l� \8k�bR�K}Q�:�Câ��8�!�(��I5��6�}�xd�{���v���G���}�'��f<���c��������>��~m}|�l>��� ��Ǎ4�]�l����ϕ��Ǘ���3��1�ُ��b_�π�}��2=��B��G�m��^�x�7,+9m[�F�EW0i-�6- �"��<���"H��S��I�Db�{������)���|����BIL�d�������L&� ����a_��A��!�o�y{Iw���*T�Md�E����I�x�Q����=sv34��{���d�Y*8_-潏��K �ǭ���\ͪ2f:�%sp*�܂�#�҉tďu5���' �t!�\�f�}ֻ�9��ak�2���(� �8���qs�޻�5��P�y�3e2P��7��W5��s�����Dߐn�4��,d[cBk�,�����&o>�2��>o?���S�I�X�ڭ�T�� �#G��K�>\� d�wL�&v'����Zty��b����i�8���Plgj��J���='���j����Y�n�帨��#�ի�\Z�����K��}w�mF3��?+�nMf0���T��-�45�m���,�-��JV$ad �!�(�u� �8��!Q��>"{���������W>�3� �5Rӣe}��H��S9�sw �Puf�Ud�5�2���*�9f$anys)D���x?{U<ߣ��d.�g�F7��4���˲�Uf�\��ͧq�lѱ%����&��F'Hp�\�#�J�08Ā+�H#�9w6n�]��k������8ک�_Y�~�E�%��۸�{p��]F�2,Y�ػ�|x�[�(��g
please, what could possibly be wrong with my code?, any help and i will be so grateful.
The path C:wamp/www looks peculiar, should there not be a slash after the colon? Anyway, when sending files I have always used as below so perhaps it will be useful.
foreach ($idsonly as $key=>$price) {
if($curencyarray[$key]=="Internet Download"){
$dfr = $productidarray[$key].'.'.$itemformatarray[$key];
$file = 'C:/wamp/www/allcars/Dhotois/'.$bigidarray[$key].'/'.$dfr;
$fie = str_replace("; charset=binary","",$mimeformarray[$key]);
$filename = $dfr;
$filepath = "C:/wamp/www/allcars/Dhotois/".$bigidarray[$key]."/" . $filename;
if( realpath( $filepath ) ){
set_time_limit(0);
ignore_user_abort(false);
ini_set('output_buffering', 0);
ini_set('zlib.output_compression', 0);
header("Content-Description: File Transfer");
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: ".$fie."");
header("Content-Disposition: attachment; filename=".basename($filepath));
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".#filesize($filepath));
set_time_limit(0);
/* send the file piece by piece */
if( $file = fopen( $filepath, 'rb' ) ) {
while( !feof( $file ) and ( connection_status()==0 ) ) {
print( fread( $file, 1024*8 ) );
flush();
}
fclose( $file );
}
ob_clean();
}
}
}
I have a function especially for sending files, it's basic but works and can be extended to include the other headers you set above.
function sendfile( $filename, $filepath ) {
if( file_exists( $filepath ) ) {
if( !is_file( $filepath ) or connection_status()!=0 ) { return FALSE; }
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Expires: ".gmdate("D, d M Y H:i:s", mktime(date("H")+2, date("i"), date("s"), date("m"), date("d"), date("Y")))." GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
header("Content-Type: application/octet-stream");
header("Content-Length: ".(string)( filesize( $filepath ) ) );
header("Content-Disposition: inline; filename={$filename}");
header("Content-Transfer-Encoding: binary\n");
if( $file = fopen( $filepath, 'rb' ) ) {
while( !feof( $file ) and ( connection_status()==0 ) ) {
print( fread( $file, 1024*8 ) );
flush();
}
fclose( $file );
}
clearstatcache();
return( ( connection_status()==0 ) and !connection_aborted() );
}
}
$result=sendfile('mypicture.jpg','c:/wwwroot/images/banana.jpg');

php download script not working

The below .php script doesn't work for me - it just prints jibberish:
<?php
$path = $_SERVER['DOCUMENT_ROOT']."/rapcDemo/documents/";
$fullPath = $path.$_GET['download_file'];
if ($fd = fopen ($fullPath, "r")) {
$fsize = filesize($fullPath);
$path_parts = pathinfo($fullPath);
$ext = strtolower($path_parts["extension"]);
switch ($ext) {
case "pdf":
header("Content-type: application/pdf"); // add here more headers for diff. extensions
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a download
break;
default;
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
}
header("Content-length: $fsize");
header("Cache-control: private"); //use this to open files directly
while(!feof($fd)) {
$buffer = fread($fd, 2048);
echo $buffer;
}
}
fclose ($fd);
?>
Any ideas what I am doing wrong?
Well... This is the script I use. Maybe it will help.
Main donwload script:
<?php
$path = $_SERVER['DOCUMENT_ROOT']."/rapcDemo/documents/";
$fullPath = $path.$_GET['download_file'];
if(is_file($fullPath)) {
# required for IE
if (ini_get('zlib.output_compression')) {
ini_set('zlib.output_compression', 'Off');
}
# get the file mime type using custom function
$mime = ($try = get_mime($fullPath)) ? $try : "application/octet-stream";
# set headers for download
header('Pragma: public'); // required
header('Expires: 0'); // no cache
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($fullPath)) . ' GMT');
header('Cache-Control: private', false);
header('Content-Type: ' . $mime);
header('Content-Disposition: attachment; filename="' . $_GET['download_file']. '"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($fullPath)); // provide file size
header('Connection: close');
readfile($fullPath); // push it out
exit();
}
?>
And this is my get_mime() function:
<?php
function get_mime($url = "") {
if (empty($url))
return FALSE;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$results = explode("\n", trim(curl_exec($ch)));
foreach ($results as $line)
if (strtok($line, ':') == 'Content-Type')
return trim(explode(":", $line)[1]);
return FALSE;
}
?>
Ok! I just found and modified a php script online that works like a charm:)
The link is below:
http://phpsnips.com/579/PHP-download-script-for-Large-File-Downloads

X-Sendfile notification after finish download

I would need to set the download status to 0 when download has finished. I am using x-sendfile, but after finish download, dont set status.
My code:
header("X-Sendfile: $file");
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . $name . '"');
mysql_query("UPDATE `downloads` SET `download_status` = '1' WHERE `id` = '" . $last_down . "'");
Thanks for help
You can't detect when the client finished downloading the file if you using X-Sendfile.
Simplest way is stream file by script.
$handle = fopen($filepath, 'rb');
if ($handle !== false) {
#flock($handle, LOCK_SH);
$size = filesize($filepath);
$filename = basename($filepath);
$old_max_execution_time = ini_get('max_execution_time');
ini_set('max_execution_time', 0);
$old_cache_limiter = session_cache_limiter();
session_cache_limiter(false);
if (ob_get_length()) ob_clean();
header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: binary');
header('Content-disposition: attachment; filename="'. $filename .'"');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Accept-Ranges: bytes');
header('Cache-control: private');
header('Pragma: private');
set_time_limit(0);
while (! feof($handle) && (connection_status() === 0)) {
if (! $buffer = #fread($handle, $interval)) {
// Error
exit;
}
print($buffer);
flush();
}
#flock($handle, LOCK_UN);
#fclose($handle);
ini_set('max_execution_time', $old_max_execution_time);
session_cache_limiter($old_cache_limiter);
// ----------------------------------------------------
// Downloading complete!
// Here you can update your table row in DB...
// ----------------------------------------------------
exit;
}

Categories