Save file in some specific location using content disposition - php

Below code works perfectly to download the .html file of a current PHP web page
$filename = 'filename.html';
header('Content-disposition: inline; filename=' . $filename);
header('Content-type: text/html');
Is there any way to save file in some specific location instead the download response.
Ex: if i want to save this filename.html file in location /export/www/html/myproject/var/htmlpages
Tried below logic as alternative also:
ob_start();
file_put_contents('myfile.html', ob_get_contents());
But its generating empty file

Use fopen() to write a file in a specific directory instead of download response like:
<?php
$fp = fopen('data.txt', 'w'); // here you can pass the directory path + filename
fwrite($fp, '1');
fwrite($fp, '23');
fclose($fp);
?>
fwrite() doc

Related

Have file data (garbage code) - need to download actual file

We are receiving file data from a third party API call that returns the content type in one variable and the file contents in another. The file contents are "garbage code." For example:
$doc->fileContents = "A�[�j쎪A����Kb����m��= ....";
$doc->fileType = "application/msword";
I need to be able to provide my users a clickable method for downloading the file, but simply writing the contents to a file and forcing a download with that content type simply opens a file containing all that garbage... not the real file contents.
EDIT: Per Patrick Q's request, I did it the standard fwrite way:
$fp = fopen($filename, 'w'); // filename is generated elsewhere
fwrite($fp, $doc->fileContents);
fclose($fp);
So the question is, how do I create a real, usable file out of this garbage?
The data looks like binary file data. There's no need to write it to a file first, just make sure you set the Content-Transfer-Encoding header to binary when you send it to the browser for downloading.
I'm assuming you already have a way of mapping $doc->fileType to a filename with the proper extension, I'll just hardwire .doc here since your example is an application/msword document.
// your logic here to determine the filename sent to the browser
$filename = "file.doc";
// set the minimum appropriate HTTP headers
header('Content-Type: ' . $doc->fileType);
header('Content-Length: ' . strlen($doc->fileContents));
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary'); // this is an important one
// send the file and stop
echo $doc->fileContents;
exit;
If you are writing it to file first, make sure you open it in binary mode:
$fp = fopen($filename, 'wb');
fwrite($fp, $doc->fileContents);
fclose($fp);

Remove file after fpassthru, is there a callback?

This could works perfectly in passing a zipped file back to the client. But the little snippet at the end unlinking the file doesn't seem to be working?
I am assuming that the fpassthru locks the file, so the unlink cannot do anything..
Is there a callback option available.. something to remove the file after the client has received it?
// we deliver a zip file
header("Content-Type: archive/zip");
// filename for the browser to save the zip file
header("Content-Disposition: attachment; filename=$guideName".".zip");
$filesize = filesize($zip_file);
header("Content-Length: $filesize");
// deliver the zip file
$fp = fopen($zip_file,'r');
echo fpassthru($fp);
// clean up the tmp zip file
unlink($zip_file);
exit();
While the file is opened, it's locked and cannot be deleted.
fclose($fp);
unlink($zip_file);
Also make sure the file is writable by the www-user / fpm script owner (=> chmod).
To debug this, I suggest a combination of error reporting, output buffers and mail:
ob_start();
error_reporting(E_ALL);
fclose($fp);
unlink($zip_file);
$debug = ob_get_contents();
mail('you#server', 'error in zip upload', var_export($debug, true));
Another sidenote is the concatenation here:
("Content-Disposition: attachment; filename=$guideName".".zip")
Properly:
("Content-Disposition: attachment; filename=" . $guideName . ".zip")
You could also use file_get_contents() which is basically the same as fopen, fpassthru, fclose in once:
header("Content-Length: $filesize");
// deliver the zip file
echo file_get_contents($zip_file);
// clean up the tmp zip file
unlink($zip_file);
You are ceating a file handle with the call to fopen, which is what will be locking the file. You need to ensure that you call fclose before unlink. E.g.
$fp = fopen($zip_file,'r');
echo fpassthru($fp);
fclose($fp);
unlink($zip_file);
First of all there is an error in your code which will most likely corrupt the file you are sending:
Return values
If an error occurs, fpassthru() returns FALSE. Otherwise, fpassthru()
returns the number of characters read from handle and passed through
to the output.
Therefore your code should look like:
// deliver the zip file
$fp = fopen($zip_file,'r');
fpassthru($fp);
Notice there is no echo before fpassthru.
A MUCH more reliable solution would be to run a separate script to clean the folder where these files are stored every x minutes/hours/days.
If the file is open and you delete it, it is still open and can be read from, but no longer accessible by file name. When script terminates and file handle is closed the space taken by the file will be freed.
The other possible way is using session shutdown handler.

Help understand this PHP code download file

I want to download a doc file located at http://confluence.rogersdigitalmedia.com/exportword?pageId=1114407. How can I modify the following code to download a file from that URL??
And can someone please explain what this code does in its current state, what does it download, a file from a directory?
<?php
// place this code inside a php file and call it f.e. "download.php"
$path = $_SERVER['DOCUMENT_ROOT']."/path2file/"; // change the path to fit your websites document structure
$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);
exit;
// example: place this kind of link into the document where the file download is offered:
// Download here
?>
This code is supposed to download files through PHP. Usually, it's used to hide the directory containing the downloads, or to download files which were otherwise inaccessible because the files are outside the web root. Another use for such a script is to offer downloads for authorized users, you'd have to put an authentication check in the script.
If the file has a PDF extension, the download is offered as with the PDF mimetype, so browsers can open it in a PDF viewer. Other files are offered as binary files which can be saved.
Do not use this script "as-is". It contains a huge security vulnerability which allows an attacker to view arbitrary files on your system (Path traversal). Replace line:
$fullPath = $path.$_GET['download_file'];
with the following to make it a bit more secure:
$fullPath = $path . basename($_GET['download_file']);
Even better: implement whitelisting by allowing filenames within an allowed character set and rejecting other invalid filenames.
Downloading an external file is as easy as following the example of cURL:
<?php
$ch = curl_init("http://www.example.com/");
$fp = fopen("example_homepage.txt", "w");
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($fp);
?>
Since I've no clue about the URL of your download, I'll leave the original URLs and filenames from the PHP example.
This code is something you put on your own server to allow people to download files through PHP. Usually you'd add some authentication code in there so PHP can accept/reject the user before downloading.

downloading a csv file

im having a problem when downloading a csv file using php, ideally i want to visit a page and it just prom,pts me to save the file-
i have tried this here-
$filename = 'dump.csv';
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
and it has been returning a empty file, even though when i do-
echo filesize($filename);
it returns 19000 ?
You have to read the content of the file in and then output it.
Otherwise you are just sending the headers telling the browser to expect the file.
You would need to echo out the contents of the file. For example, after your header functions you would have something like:
$fh = fopen($filename, "r");
while($line = fgets($fh)){
echo $line;
}
fclose($fh);

How do I use my server as a proxy to download files via PHP?

I need my server to act as a proxy between a 3rd party server (where the file is originally located) and the end user. That is, my server downloads the file from the 3rd party server, and sequentially, the user downloads it from my server. This should result in an incurred bandwidth of twice the file size. How can this process be achieved using PHP?
Very very simply like this:
$url = $_GET['file'];
$path_parts = pathinfo($url);
$ext = $path_parts['extension'];
$filename = $path_parts['filename'];
header("Content-type: application/$ext");
header("Content-Disposition: attachment; filename=$filename");
echo file_get_contents($url);
If the file is larger than a few megabytes, use fopen fread and frwrite download the file in chunks and send to the client in chunks.
$fp = fopen($url, 'rb');
foreach (get_headers($url) as $header)
{
header($header);
}
fpassthru($fp);
exit;
This will simply download a remote file to the browser with correct headers.
file_get_contents() will not load the page until the entire file is downloaded to memory
readfile() will show the page right away yet continue downloading the file in memory, streaming it to the client
Example usage using an EXE:
$url = "https://path/to/file.exe";
$filename = "SaveAsFile.exe
header("Content-Disposition: attachment; filename=$filename");
readfile($url);

Categories