I'm doing file download with renaming it before. Everything works except size. I can't set file size with
header('Content-Length: ');
even I'm setting it to
header('Content-Length: 15444544545');
it's not working. I'm using PHP codeigniter framework, where is the problem?
EDIT: more code:
$file_data = array(
'originalName' => $post_info['file_info'][0]['original_name'],
'fakeName' => $post_info['file_info'][0]['file_name'],
'modificationId' => $post_info['file_info'][0]['modification_article_id'],
'extension' => end(explode('.', $post_info['file_info'][0]['original_name'])),
'name' => str_replace(".".end(explode('.', $post_info['file_info'][0]['original_name'])), "", $post_info['file_info'][0]['original_name']),
'filesize' => filesize($post_info['file_info'][0]['file_name'])
);
header('Cache-Control: public');
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename=' . $file_data['name'] . '.' . $file_data['extension']);
header('Content-Length: ' . filesize(base_url().$file_data['fakeName']));
// Read file
readfile(base_url().$file_data['fakeName']);
//print_r($file_data);
echo "<script>window.close();</script>";
EDIT: Solution
there was a server problem
You can try like this:
$mm_type="application/octet-stream";
header("Cache-Control: public, must-revalidate");
header("Pragma: hack");
header("Content-Type: " . $mm_type);
header("Content-Length: " .(string)(filesize($fullpath)) );
header('Content-Disposition: attachment; filename="'.$filename.'"');
header("Content-Transfer-Encoding: binary\n");
readfile($fullpath);
wrong usage of base_url().
where is your file stored?
maybe you can try the constant FCPATH instead of call function base_url()
and you have the filesize stored in $file_data['filesize']
finally there should not be a line echo "<script>window.close();</script>"; in your php script when the file content was output.
You tried with download_helper?? Sintax: force_download($filename, $data).
Also in your code you're reading file through URL. Use file system path instead.
From controller action:
<?php
public function download()
{
//Your code here...
$filePath = realpath(FCPATH.DIRECTORY_SEPARATOR.'uploads/myfile.pdf'); //FakeName????
force_download($file_data['fakeName'], readfile($filePath));
}
If my solution don't works give me a touch to give you other way.
Note: FCPATH is the front controller path, a public folder of server e.g.(/var/www/CodeIgniter). Other path constants are already defined on index.php (front-controller).
A print of $file_data['fakeName'] will be useful.
If your CodeIgniter version don't have download_helper make your own... refer to CI docs for full explanation. There is the force_download function code:
function force_download($filename = '', $data = '')
{
if ($filename == '' OR $data == '')
{
return FALSE;
}
// Try to determine if the filename includes a file extension.
// We need it in order to set the MIME type
if (FALSE === strpos($filename, '.'))
{
return FALSE;
}
// Grab the file extension
$x = explode('.', $filename);
$extension = end($x);
// Load the mime types
if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
{
include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php');
}
elseif (is_file(APPPATH.'config/mimes.php'))
{
include(APPPATH.'config/mimes.php');
}
// Set a default mime if we can't find it
if ( ! isset($mimes[$extension]))
{
$mime = 'application/octet-stream';
}
else
{
$mime = (is_array($mimes[$extension])) ? $mimes[$extension][0] : $mimes[$extension];
}
// Generate the server headers
if (strpos($_SERVER['HTTP_USER_AGENT'], "MSIE") !== FALSE)
{
header('Content-Type: "'.$mime.'"');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Transfer-Encoding: binary");
header('Pragma: public');
header("Content-Length: ".strlen($data));
}
else
{
header('Content-Type: "'.$mime.'"');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header("Content-Transfer-Encoding: binary");
header('Expires: 0');
header('Pragma: no-cache');
header("Content-Length: ".strlen($data));
}
exit($data);
}
Related
I am using following code to download csv file.
static function download(){
$wooe_download = filter_input(INPUT_GET, 'woooe_download', FILTER_DEFAULT);
$wooe_filename = filter_input(INPUT_GET, 'filename', FILTER_DEFAULT);
if( !empty($wooe_filename) && !empty($wooe_download) && file_exists(path_join( self::upload_dir(), $wooe_filename.'.csv'))
&& wp_verify_nonce($wooe_download, 'woooe_download')
)
{
$charset = get_option('blog_charset');
$csv_file = path_join( self::upload_dir(), $wooe_filename.'.csv');
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header("Content-Disposition: attachment; filename=". self::filename());
header("Expires: 0");
header('Cache-Control: must-revalidate');
header('Content-Encoding: '. $charset);
header('Pragma: public');
//header('Content-type: text/csv; charset='. $charset);
header('Content-Length: ' . filesize($csv_file));
//header("Pragma: public");
readfile($csv_file);
//unlink($csv_file);
exit;
}
}
File is getting downloaded twice in browser. I am not sure how to restrict it to only once?
I try to force download a pdf file from php that are in server...but all the file that i download only 1kb size.It not the same with actual size do i need to declare file size before download?
<?php
$path = "C:\Users\omamu02\Desktop\TESTPRINT" ;
$file = "NMT PRV PHG 370 2017.pdf";
header("Pragma: public");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-disposition: attachment; filename= $file"); //Tell the filename to the browser
header("Content-type: application/force-download");//Get and show report format
header("Content-Transfer-Encoding: binary");
header("Accept-Ranges: bytes");
readfile($path); //Read and stream the file
get_curret_user();
error_reporting(0);
?>
First of all, you should fix your filename= $file header. Wrap your $file variable with a ' chars at least. Also, you don't need the closing tag in the end of the PHP file.
And I'm not sure about your headers, so I suggest you try the function below, it's quite common for any type of data and already contains some bugfixes and workarounds:
function download_file($file_path, $file_name = null, $file_type = 'application/octet-stream')
{
if ($file_name === null)
{
$file_name = basename($file_path);
}
if (file_exists($file_path))
{
#set_time_limit(0);
header('Content-Description: File Transfer');
header('Content-Type: ' . $file_type);
header('Content-Disposition: attachment; filename="' . str_replace('"', "'", $file_name) . '"');
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_path));
readfile($file_path);
}
exit;
}
I have written following code in my Yii framework controller. This code is working fine on my localhost but not working on server.
Can somebody please tell me whats wrong with the code
Following is my code which I have written in controller
public function downloadFile($dir,$file,$extensions=[]){
if(is_dir($dir)){
$path = $dir.$file;
if(is_file($path)){
$fileinfo=pathinfo($path);
$extension=$fileinfo["extension"];
if(is_array($extensions)){
foreach($extensions as $e){
if($e===$extension){
$size = filesize($path);
header('Content-Type: application/octet-stream');
header('Content-Length: '.$size);
header('Content-Disposition: attachment; filename='.$file);
header('Content-Transfer-Encoding: binary');
readfile($path);
return true;
}
}
}
}else{
echo"error";
}
}
}
public function actionDownload(){
if(Yii::$app->request->get('file')){
$this->downloadFile("media/offer/",Html::encode($_GET["file"]),["jpg","png"]);
}
}
You tagged yii2, but it's not yii2, its pure php.
How about use framework to do this?
public function actionFile($filename)
{
$storagePath = Yii::getAlias('#app/files');
// check filename for allowed chars (do not allow ../ to avoid security issue: downloading arbitrary files)
if (!preg_match('/^[a-z0-9]+\.[a-z0-9]+$/i', $filename) || !is_file("$storagePath/$filename")) {
throw new \yii\web\NotFoundHttpException('The file does not exists.');
}
return Yii::$app->response->sendFile("$storagePath/$filename", $filename);
}
Yii2 - sendFile()
^Change storagePath to your file directory.
And that's all, nothing more to do.
Replace this function with yours,
public function downloadFile($dir,$file,$extensions=[]){
if(is_dir($dir)){
$path = $dir.$file;
if(is_file($path)){
$fileinfo=pathinfo($path);
$extension=$fileinfo["extension"];
if(is_array($extensions) && in_array($extension, $extensions)){
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');
header('Pragma: public');
header('Content-Length: ' . filesize($path));
ob_clean();
flush();
readfile($path);
exit;
}
}else{
echo"error";
}
}
}
I just called this with following,
downloadFile("/var/www/html/", "test.php", ['php']);
and it worked for me.
Regarding downloading files and defining the headers, I am having trouble assigning a dynamic filename to my files. When using the code below :
header("Content-Disposition: attachment; filename=test.csv");
A test.csv file is generated for download. However if I use this:
header('Content-Disposition: attachment; filename=' . $filename . '.csv');
It generates a .php file instead. Using this method also doesn't pass the Content-Disposition or filename to the header.
Full code:
session_start();
$file =$_SESSION['csvf'];
$filename = $file."_".date("Y-m-d_H-i",time());
header ( "Content-type: text/csv" );
header("Content-Disposition: attachment; filename=test.csv");
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
print($file);
exit ();
What is the correct syntax?
EDIT
Working Code after suggestions
session_start ();
$file = $_SESSION ['csvf'];
$filename =date ( "Y-m-d_H-i", time () );
header ( "Content-type: text/csv" );
header ( "Content-Disposition: attachment; filename=".$filename );
header ( 'Expires: 0' );
header ( 'Cache-Control: must-revalidate' );
header ( 'Pragma: public' );
header ( 'Content-Length: ' . filesize ( $file ) );
print ($file) ;
exit ();
I don't see the path to example.csv specified on your code, you need to give the full path to $file, i.e.:
$mySession = $_SESSION['csvf'];
//since $_SESSION['csvf'] contains the actual data you cannot use it for filename
$filename = date("Y-m-d_H-i",time()).".csv";
//write $mySession contents to file. Make sure this folder is writable
file_put_contents("/home/site/csvfolder/$filename", $mySession);
$file = "/home/site/csvfolder/$filename";
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-type: text/csv');
header('Content-Disposition: attachment; filename='.$filename);
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
Please Use Like as follows,I am using this for me.
header("Content-Type: application/vnd.ms-excel; charset=utf-8");
header("Content-Disposition: attachment; filename=".$fileName);
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
In place of application/vnd.ms-excel use your file format.It is for Microsoft Excel.
Try with this:
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=test.csv');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
You can see more about download files with PHP here:
http://php.net/manual/en/function.readfile.php
Try With Below code , it's work for me
$file =$_SESSION['csvf'];
$filename = $file."_".date("Y-m-d_H-i",time()).".csv";
header ( "Content-type: text/csv" );
header("Content-Disposition: attachment; filename=".$filename);
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
print($file);
exit ();
Below is a snippet for a .zip file with some descriptions on some information that header requires, perhaps a good practice is to get the information and some validations before writing headers.
Another shorter example is also included,
// defines filename, type, path, size and a reference to file (handler)
// to set as values for file header
$filename = $survey_id . '.zip';
// define path to the file to be get file size on the next line
$filepath = [path to file]. '/' . $filename;
// used by 'Content-length'
$filesize = filesize($filepath);
// using fopen to get a file handler, 'r' for read, 'b' for binary (zip file)
$file_pointer = fopen($filepath, 'rb');
// check if file exists
if(is_file($filepath))
{
// valid file?
if($filesize && $file_pointer)
{
// some required header information to describe file, see [docs][1]
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: zip file");
header("Content-Type: application/zip");
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=" . $filename);
header("Content-Transfer-Encoding: binary");
header("Content-length: " . $filesize);
fpassthru($file_pointer);
// close
fclose($file_pointer);
}
}
Also, checkout readfile(), a shorter snippet below
<?php
$file = 'monkey.gif';
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;
}
?>
Hope this helps!
Just escape your php properly like so:
header('Content-Disposition: attachment; filename=' . time() . '.export.csv');
This example will put a UNIX timestamp prepended to the file name. Of course you could get crazy with programmatically using variables or inbuilt php functions, but this is just the example.
Here is more of an example. This file name will be produced when running this php code.
2019-05-18-contacts-main-export-by-Garrick.csv
header('Content-Disposition: attachment; filename=' . date("Y-m-d") . '-contacts-main-export-by-' . $uidName . '.csv');
I am trying to download image file in CI but getting error when I open download image file. Need help :(
$file_name = $_GET['file_name'];
$file_path = "./ups_printimages/".$file_name;
if(file_exists($file_path))
{
$this->load->helper('download');
$data = file_get_contents($file_path); // Read the file's contents
$name = 'ups_label.png';
force_download($name, $data);
}
else
{
echo "file does not exist";
}
GOD. Found out the solution :)
if(!file)
{
File doesn't exist, output error
die('file not found');
}
else
{
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, post-check=0, pre-check=0');
header('Pragma: public');
ob_clean();
flush();
readfile($file);
exit;
}
Use header to force download. Use the code below
$file_name = $_GET['file_name'];
$file_path = "./ups_printimages/".$file_name;
if(file_exists($file_path))
{
header('Content-Type: image/jpeg');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . basename($file_name) . "\"");
readfile($file_path);
}
else
{
echo "file does not exist";
}
Hope this helps yoiu