I have gone through all articles on Stack Overflow and can't fix my issue. I am using following code:
$file = $_GET['url'];
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
The above mention code is downloading the file from the directly above the root and Yes it is downloading a PDF file but the file is only of 1KB size and not the original size. The $_GET['url'] is receiving ../dir/dir/filename.pdf in it. the filename is space in it as well. For security reason I cannot share the file name.
Please let me know where am I going wrong.
Please make sure you are using the web server path to access the file - for instance your path could be: /home/yourusername/public/sitename/downloads/<filename>, you should check first - to help you can run this at the top of your PHP script to find out the full path for the current script:
echo '<pre>FILE PATH: '.print_r(__FILE__, true).'</pre>';
die();
Only send the filename with the url using urlencode() and on the receiving PHP script use urldecode() to handle any character encoding issues.
See here: http://php.net/manual/en/function.urlencode.php
and here: http://php.net/manual/en/function.urldecode.php
So where you create your url:
Download File
And in your php script:
$file_base_path = '/home/yourusername/public/sitename/downloads/';
$file = urldecode($_GET['url']);
$file = $file_base_path . $file;
$file = $_GET['url'];
if (file_exists($file))
{
if (FALSE!== ($handler = fopen($file, 'r')))
{
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: chunked'); //changed to chunked
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
//header('Content-Length: ' . filesize($file)); //Remove
//Send the content in chunks
while(false !== ($chunk = fread($handler,4096)))
{
echo $chunk;
}
}
exit;
}
echo "<h1>Content error</h1><p>The file does not exist!</p>";
I hope this helps you!
Related
While writing a PHP-Script, im stuck at an issue i cant resolve.
The PHP-Script consist in letting a user download a .mp4 file. The download works without any issues but the file downloaded can not be played.
Heres the code:
<?php
$filepath = "/www/servermedia/technounion.mp4";
$filename = basename($filepath);
header("Content-type: video/mp4");
header("Content-Disposition: attachment; filename=.$filename");
readfile($filename);
exit;
?>
After the .mp4 file gets downloaded, it cannot be played.
It looks like this:
The error message means that Windows Media Player cannot play back the file because probably the player doesnt support the codec. I already tried with VLC but it does not work either.
EDIT:
Comparing both file sizes, the downloaded file is only a couple bytes large instead of the 3,73 MB of the file on the server
Your code is not well-formed, you miss to escape double-quotes by adding single-quotes as I done here, please test my answer.
<?php
$filepath = "/www/servermedia/technounion.mp4";
$filename = basename($filepath);
header('Content-Type: video/mp4');
header('Content-Disposition: attachment; filename="' . $filename . '"');
readfile($filename);
exit;
?>
But I suggest a more complex way:
<?php
$filepath = $_SERVER['DOCUMENT_ROOT'] . "/www/servermedia/technounion.mp4";
$filename = basename($filepath);
header('Content-Type: video/mp4');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . sprintf("%u", filesize($filepath)));
set_time_limit(0);
$fh = fopen($filepath, "rb");
while (!feof($fh)) {
echo fgets($fh);
ob_flush();
flush();
}
fclose($fh);
exit;
?>
$_SERVER['DOCUMENT_ROOT'] is useful to get the full path from the server
set_time_limit(0) is useful to avoid any timeout during download
fgets() is useful for reading large files
ob_flush() and flush() assure that there is not other output in the buffer
I hope this helps.
Is the downloaded file the exact same filesize?
Does the content type exist in your webserver?
header("Content-Type: video/mp4"); Note capital 'T' for type.
This maybe worth testing with to see you can serve the file content inline:
http://www.phpmind.com/blog/2016/10/how-to-use-php-to-output-an-mp4-video/
I am not able to open the file after the download.
It says the the file has been corrupted.
I guess i have used all the required headers fine.
In chrome it shows error like:
chrome resource interpreted as document but transferred with mime type application/octet-stream
In Firefox no error msg.
if (isset($_GET['file']) && basename($_GET['file']) == $_GET['file']) {
$filename = $_GET['file'];
} else {
$filename = NULL;
}
$err = 'Sorry, the file you are requesting is unavailable.';
if ($filename) {
// define the path to your download folder plus assign the file name
$path = '/wp-content/uploads/'. $filename;
// check that file exists and is readable
if (file_exists($path)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'. basename($path) . '"');
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($path));
ob_end_clean();
flush();
readfile($path);
exit;
}
}
download: getting downloaded from ftp folder.
None of the formats are opening.
.txt is getting opened.
Let me know if i am in wrong direction.
Inserting into table:
echo "<tr><a href='?file=". $row["FileupName"]."'>".$row["FileupName"]."</td></tr>";
readfile('$path') is your issue, it should be readfile($path) (with no quotes)
In PHP, variables are only evaluated in strings if the string is defined in double quotes ". Effectively you're downloading a file where the contents is the literal string '$path', with an incorrect filesize.
In the website page contains many images with downloading options. If I click the download button it automatically downloaded on user system and it shows on browser downloadable page. I have PHP code like
$image = file_get_contents('http://website.com/images/logo.png');
file_put_contents('C:/Users/ASUS/Downloads/image.jpg', $image);
Above coding is working fine. But I need to provide the path name for image to save. In user side we don`t know the path.
I need the PHP code to use the browser download location and download images need to show the browser downloads.
not possible to store the image in particular user location due to security issues .you don't force user .you have to suggest him to store particular location .and also you don't know the what file system there in user system.and also downloading path can be setting up by user anywhere so your not able to get that.
$filename = '/images/'.basename($_POST['text']);
file_put_contents($filename, $content);
you have to save/download the image somewhere on your web serwer and next send the file to user using header function, for example:
$file = 'path_to_image';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
else {
echo "file not exists";
}
manual
`<?php
$filename ='http://website.com/images/logo.png';
$size = #getimagesize($filename);
$fp = #fopen($filename, "rb");
if ($size && $fp)
{
header("Content-type: {$size['mime']}");
header("Content-Length: " . filesize($filename));
header("Content-Disposition: attachment; filename=$filename");
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
fpassthru($fp);
exit;
}
header("HTTP/1.0 404 Not Found");
?>`
I have code to serve requested files in PHP. It's testing code, so input is not validated. (By the way, how to correctly sanitize this kind of input...)
$upload_dir = "/media/usb/dir";
$filename = $_GET['filename'];
$mimetype = $_GET['mime'];
$path = $upload_dir . $filename;
header('Content-Description: File Transfer');
header("Content-Type: ".$mimetype );
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($path));
header("X-Sendfile: \"$path\"");
echo readfile($path);
But size of file in bytes is appended to each file.
For example simple txt like this:
myfile
Will become this:
myfile6
How to get rid of this behaviour?
I'm getting textfile like this:
download.php?mime=text/plain&filename=my-file.txt
readfile() returns the size of the file. You can add # to the beginning of the function to remove the error reporting. echo #readfile($path); should display only the filename.
I am trying to write a script in Yii for downloading files from the server.
The files are located in webroot of the Yii project,
but I got every time file not exist error, could anyone see where is wrong:
public function actionDownload($id) {
$audio = Audio::model()->findByPk($id);
$file = Yii::getPathOfAlias('webroot') . $audio->path;
if (file_exists($file)) {
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $audio->path);
header('Content-Length: ' . filesize($audio->path));
$audio->downloaded = $audio->downloaded + 1;
$audio->save();
}else{
echo "file not exist: ".$file;
}
exit;
}
error I got is:
file not exist: /var/www/vhosts/ikhwanbiz.org/httpdocs/userfiles/reklames/media/deneme/sen%20dep%20olmisem.mp3
Thanks
Regards
Bili
Bili, this works well for me and seem to be fine on most browsers.
$filename = 'your_file_name.csv';
header('Content-Disposition: attachment; charset=UTF-8; filename="'.$filename.'"');
$utf8_content = mb_convert_encoding($content, "SJIS", "UTF-8");
echo $utf8_content;
Yii::app()->end();
return;
Hope it helps, good luck!
It looks like the filename portion $audio->path is URL-encoded, while the name of the actual file on the server is not. You should fix it at the source (no idea where that path is set from), but in the meantime an easy workaround would be to write
$file = Yii::getPathOfAlias('webroot') . urldecode($audio->path);
This is more of a php question than a yii one.
for eg,
<?php
header("Content-disposition: attachment; filename=huge_document.pdf");
header("Content-type: application/pdf");
readfile("huge_document.pdf");
?>
source: http://webdesign.about.com/od/php/ht/force_download.htm