again i try to prevent form caching mp3 files form my site. I use flash player, all files are outside public html i use this script to access to files
<?php
$file = $_GET['file'] . '.mp3';
$fileDir = '/path/outside/public_html/';
if (file_exists($fileDir . $file))
{
ob_start();
$contents = file_get_contents($fileDir . $file);
echo $contents;
$buffer = ob_get_contents();
ob_end_flush();
header('Expires: Mon, 26 Jul 1980 00:00:00 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Cache-Control: post-check=0, precheck=0', false);
header('Pragma: no-cache');
header('Content-type: audio/mpeg');
echo $buffer;
} ?>
I'm php noob so this script is probably buggy, but it's work... Almost, i have problem to prevent file cache in Opera - it still cache mp3 files. I saw some solution: when i play files from site, file was downloaded to cache but after full download file was automaticly delete. There is no time to copy this file. So my question is: ho do this ? Is this possible with php?
This issue can be caused by server itself, to prevent file caching try to add some extra parameter to file name like:
$file = $_GET['file'] . '.mp3?' . time();
Related
This php file is supposed to:
receive a piece of information from a form on a different page
use this information to create an array of file paths to add to a zip file
create a dynamically named zip file using a class that's included.
force the download of the newly created zip file
numbers 1-3 are working flawlessly.
The page even forces the download of a zip file that is correctly named and is the right size, but when I try to open it, it says the file is invalid. I've seen similar problems in searches, but I have yet to find a solution.
If i enter the direct URL for the newly created zip into the browser, the file downloads and opens perfectly. As a matter of fact, my temporary fix was creating a dynamic direct link to the files :/
I should probably mention that this is hosted on the go daddy economy plan.
<?php
error_reporting(0);
include "gavScripts/connect_to_mysql.php";
require_once 'Zipper.php';
// prepare the file paths to add to the zip file and find the job/client name (for naming the zip folder)
if(isset($_POST['jobName']))
{
$clientID = $_POST['jobName'];
$clientSQL = mysql_query("SELECT clientName FROM job_client WHERE clientID = $clientID");
while($clientRow = mysql_fetch_array($clientSQL))
{
$clientName = $clientRow['clientName'];
}
$zipSQL = mysql_query("SELECT filePath FROM job_expense WHERE clientID = $clientID");
While($zipRow = mysql_fetch_array($zipSQL))
{
$filePaths[] = $zipRow['filePath'];
}
}
//create the zip folder and store the requested files
$zipper = new Zipper();
$zipper->add($filePaths);
$zipper->store('invoices/' . $clientName . '_Invoices.zip');
//download the zip
$fileDownload = 'invoices/' . $clientName . '_Invoices.zip';
$fileName = basename($fileDownload);
header("Content-Type: application/zip");
header("Content-Disposition: attachment; filename=" . $fileName . "");
header("Content-Length: " . filesize($fileDownload));
readfile($fileDownload);
?>
You may have trailing whitespace at the end of your script which is breaking your zip file. Is there a \r or \n (or both) after the closing ?>? Try removing the closing ?> which is optional anyway.
Try the following:
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Last-Modified: '.gmdate ('D, d M Y H:i:s', filemtime($fileName)).' GMT');
header('Cache-Control: private',false);
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="'.basename($fileName).'"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($fileName));
header('Connection: close');
readfile($fileName);
exit();
Might help.
I am using PHPPowerpoint to create a pptx file with some charts, and have no problem storing it in the same folder as the PHP script. PHPPowerpoint does that on itself.
I want to download the pptx file after it has been created, and so far I have tried every option I could locate on the web. This is how i try to do it atm.:
$file = str_replace('generate_report.php', 'export_download.pptx', __FILE__);
header('Content-Description: File Transfer');
header('Content-disposition: attachment; filename="' . $file . '"');
header('Content-Transfer-Encoding: binary');
header('Content-Type: application/vnd.openxmlformats-officedocument.presentationml.presentation');
header('Expires: 0');
header('Cache-Control: ');
header('Pragma: ');
flush();
ob_clean();
readfile($file);
Nothing is downloaded when I execute the script. My pptx is created on the server and I can open it, no problem. But it wont download the file. I got the content type from this thread: What is a correct mime type for docx, pptx etc?. I also tried with many other types. When I console log my response i get a weird string (very long), beginning like this: PKCTDD����[Content_Types].xml͗�n�0E�|E�-J��*�X�����+���m���wBhE
Also tried this:
$handle = fopen($file, 'rb');
$buffer = '';
while (!feof($handle)) {
$buffer = fread($handle, 4096);
echo $buffer;
ob_flush();
flush();
}
fclose($handle);
Anybody who can help?
The following headers should work; and it's also better streaming directly to php://output rather than save to disk file and then spooling that disk file to the browser
// Redirect output to a client’s web browser
header('Content-Type: application/vnd.openxmlformats-officedocument.presentationml.presentation');
header('Content-Disposition: attachment;filename="' . $file . '"');
header('Cache-Control: max-age=0');
// If you're serving to IE 9, then the following may be needed
header('Cache-Control: max-age=1');
// If you're serving to IE over SSL, then the following may be needed
header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
header ('Pragma: public'); // HTTP/1.0
$objWriter = PHPPowerPoint_IOFactory::createWriter($objPHPPowerPoint, 'PowerPoint2007');
$objWriter->save('php://output');
I am new to PHP and trying my hands into it. I am creating a file and writing back to it. Creating a file in some path and writing to it, works fine for me. But when i try to download the same file from the same path, its not getting downloaded instead I'm getting empty file.
header('Content-type: text/xml');
header("Content-Disposition: attachment; filename=".'check.xml');
header("Content-Length: " . filesize('./download/'.$_SESSION['user_name'].'/check.xml'));
readfile('download/'.$_SESSION['user_name'].'/check.xml');
exit;
Hi, Thanks for everyone. But I saw very unusual thing. When i downloaded the file, I didn't got the full file.
Why this case
Try removing ./ from the start of the filepath, like follows:
header('Content-type: text/xml');
header("Content-Disposition: attachment; filename=".'check.xml');
header("Content-Length: " . filesize('download/'.$_SESSION['user_name'].'/check.xml'));
readfile('download/'.$_SESSION['user_name'].'/check.xml');
exit;
With Linux file systems, ./ means the root, so that's the equivalent of / and ../ means the directory above the current directory. It's best to use absolute file paths, but simply removing the ./ should suffice.
You will also need to flush the write buffers of PHP using flush()
Here is a good working function to download a file
Here is a version adapted from that page:
public static function downloadFile($fileName) {
$filePath = $fileName;
$size = filesize($filePath);
// Taken from http://w-shadow.com/blog/2007/08/12/how-to-force-file-download-with-php/
header("Content-type: text/plain");
header("Content-Disposition: attachment; filename=\"$fileName\"");
header("Content-Transfer-Encoding: binary");
header("Accept-Ranges: bytes");
// The three lines below basically make the download non-cacheable
header("Cache-control: private");
header("Pragma: private");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Content-Length: " . $size);
if ($file = fopen($filePath, "r")) {
$buffer = fread($file, $size); // this only works for small files!
print $buffer;
flush();
fclose($file);
}
}
I'm really struggling to get my application to open a pdf when the user clicks on a link.
So far the anchor tag redirects to a page which sends headers that are:
$filename='./pdf/jobs/pdffile.pdf;
$url_download = BASE_URL . RELATIVE_PATH . $filename;
header("Content-type:application/pdf");
header("Content-Disposition:inline;filename='$filename");
readfile("downloaded.pdf");
this doesn't seem to work, has anybody successfully sorted this problem in the past?
Example 2 on w3schools shows what you are trying to achieve.
<?php
header("Content-type:application/pdf");
// It will be called downloaded.pdf
header("Content-Disposition:attachment;filename=\"downloaded.pdf\"");
// The PDF source is in original.pdf
readfile("original.pdf");
?>
Also remember that,
It is important to notice that header() must be called before any
actual output is sent (In PHP 4 and later, you can use output
buffering to solve this problem)
$name = 'file.pdf';
//file_get_contents is standard function
$content = file_get_contents($name);
header('Content-Type: application/pdf');
header('Content-Length: '.strlen( $content ));
header('Content-disposition: inline; filename="' . $name . '"');
header('Cache-Control: public, must-revalidate, max-age=0');
header('Pragma: public');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
echo $content;
There are some things to be considered in your code.
First, write those headers correctly. You will never see any server sending Content-type:application/pdf, the header is Content-Type: application/pdf, spaced, with capitalized first letters etc.
The file name in Content-Disposition is the file name only, not the full path to it, and altrough I don't know if its mandatory or not, this name comes wrapped in " not '. Also, your last ' is missing.
Content-Disposition: inline implies the file should be displayed, not downloaded. Use attachment instead.
In addition, make the file extension in upper case to make it compatible with some mobile devices. (Update: Pretty sure only Blackberries had this problem, but the world moved on from those so this may be no longer a concern)
All that being said, your code should look more like this:
<?php
$filename = './pdf/jobs/pdffile.pdf';
$fileinfo = pathinfo($filename);
$sendname = $fileinfo['filename'] . '.' . strtoupper($fileinfo['extension']);
header('Content-Type: application/pdf');
header("Content-Disposition: attachment; filename=\"$sendname\"");
header('Content-Length: ' . filesize($filename));
readfile($filename);
Technically Content-Length is optional but it is important if you want the user to be able to keep track of the download progress, and detect if the download was interrupted before the end. When using it you have to make sure you won't be send anything along with the file data. Make sure there is absolutely nothing before <?php or after ?>, not even an empty line.
I had the same problem recently and this helped me:
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="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("PATH/TO/FILE"));
ob_clean();
flush();
readfile(PATH/TO/FILE);
exit();
I found this answer here
Can you try this, readfile need the full file path.
$filename='/pdf/jobs/pdffile.pdf';
$url_download = BASE_URL . RELATIVE_PATH . $filename;
//header("Content-type:application/pdf");
header("Content-type: application/octet-stream");
header("Content-Disposition:inline;filename='".basename($filename)."'");
header('Content-Length: ' . filesize($filename));
header("Cache-control: private"); //use this to open files directly
readfile($filename);
You need to define the size of file...
header('Content-Length: ' . filesize($file));
And this line is wrong:
header("Content-Disposition:inline;filename='$filename");
You messed up quotas.
header("Content-type:application/pdf");
// It will be called downloaded.pdf thats mean define file name would be show
header("Content-Disposition:attachment;filename= $fileName ");
// The PDF source is in original.pdf
readfile($file_url);
I was wondering how I could start generating temporarily download links based on files from a protected directory (e.g. /downloads/). These links need to be valid until someone used it 5 times or so or after a week or so, after that the link shouldn't be accessible anymore.
Any help would be appreciated.
One clever solution I've stumbled upon lately if you're using apache (or lighty) is to use mod_xsendfile (http://tn123.ath.cx/mod_xsendfile/), an apache module that uses a header to determine which file to deliver to the user.
It's very simple to install (see link above), and afterward, just include these lines in your .htaccess file:
XSendFile on
XSendFileAllowAbove on
Then in your php code, do something like this when you want the user to receive the file:
header('X-Sendfile: /var/notwebroot/files/secretfile.zip')
Apache will intercept any response with an X-Sendfile header, and instead of sending whatever content you output (you may as well return a blank page), apache will deliver the file.
This takes out all the pain of dealing with mimetypes, chunking, and miscellaneous headers.
Use a database. Every time a file is downloaded the database would be updated, as soon as a certain file has reached it's limit it can be either removed or it's access could be denied. For example:
$data = $this->some_model->get_file_info($id_of_current_file);
if ( $data->max_downloads <= 5 )
{
// Allow access to the file
}
I generally keep files outside of the website directory structure for security and request like so:
function retrive_file($file_hash)
{
$this->_redirect();
$this->db->where('file_hash', $file_hash);
$query = $this->db->get('file_uploads');
if($query->num_rows() > 0)
{
$file_info = $query->row();
if($file_info->protect == 1){
$this->_checklogin();
}
$filesize = filesize($file_info->file_path . $file_info->file_name);
$file = fopen($file_info->file_path . $file_info->file_name, "r");
// Generate the server headers
if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
{
header('Content-Type: "application/octet-stream"');
header('Content-Disposition: attachment; filename="'.$file_info->file_name.'"');
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: ".$filesize);
}
else
{
header('Content-Type: "application/octet-stream"');
header('Content-Disposition: attachment; filename="'.$file_info->file_name.'"');
header("Content-Transfer-Encoding: binary");
header('Expires: 0');
header('Pragma: no-cache');
header("Content-Length: ".$filesize);
}
if($file)
{
while(!feof($file)){
set_time_limit(0);
echo fread($file, $filesize);
flush();
ob_flush();
}
}
fclose($file);
}
}
It would be pretty trivial to add byte/request counting to this.