I have a intranet site running PHP 5 that needs to list a folder containing only Excel files.
Ideally the user needs to be able to input some search criteria (ie date) and the files would be filtered into a list of hyperlinks. These hyperlinks could then be selected to download the excel file.
What I have so far is:
//get search parameters (from a form)
$s_Date = $_GET['s_Date'];
$s_Shift = $_GET['s_Shift'];
$s_Name = $_GET['s_Name'];
//search folder
foreach(glob("c:\folderA\folderB\*".$s_Date."*".$s_Shift."*".$s_Name."*.*") as $FileName)
{
echo basename($FileName);
echo"<a href=?myad=".basename($FileName)."/>Download</a>"."<br />";
}
This returns list of files but selecting hyperlinks doesn't prompt for download.
How do I get the hyperlink to force a content-type of msexcel?
Assuming you are using a PHP script to deliver the file conent, the script needs to set the Content-Type header:
<?
header('Content-Type: application/excel');
header('Content-Disposition: attachment;filename=myfile.xls');
// send file content
?>
Note you can also set the name to use for the file using the Content-Disposition header.
You might also want to consider a more well-formed <a> tag that points to your download script:
echo 'Download<br />';
In this example, you need to replace dl.php with your actual script.
Also append Content-Length header:
header('Content-Length : ' . filesize('myfile.xls'));
Client would like to know how big file is and how much of it has already been downloaded.
Related
I have got a button from where users can download specific files. Each time I will have to process the name of the file and put it in a variable before giving it to the readfile function to serve it to the user. However, in many cases the file name is quite long and may change over time so there is a potential of errors in the future. So I was wondering whether one can simply pass something like /filedirectory/*.pdf or just specify only part of the name and rest could be anything and then pass it to the readfile to download the pdf which is found there like in the example below?
if(isset($_POST["submit"]))
{
// We'll be outputting a PDF
header('Content-type: application/pdf');
// It will be called downloaded.pdf
header('Content-Disposition: attachment; filename="download.pdf"');
// Whatever name the pdf has
readfile('./filedirectory/*.pdf');
#OR
// File starts with 123..
readfile('./filedirectory/123*.pdf');
}
You can use glob to list all PDF files and then you can select the name that you wish and readfile it.
Example
<?php
foreach (glob("*.pdf") as $filename) {
// Do something with the $filename
}
?>
You may get the list of files within /filedirectory using scandir() (http://php.net/manual/en/function.scandir.php) and find out whatever a file name might be.
Here is a code which retrieves a file (say .doc) from a server, stores it in a temporary folder and then uses an api (say google viewer) to display it and then deletes it.
<?php
$body = "....."; //data from imap server
$name = "abc.doc";
$file = fopen("temp/" . $name,'w');
fwrite($file,$body);
fclose($file);
$url = rawurlencode("http://www.xxx.com/temp/".$name);
// I do not have a direct url to the file on the imap server, thus have to store it in a temporary folder
echo "<iframe src=\"http://docs.google.com/viewer?url={$url}&embedded=true\" width=\"100%\" height=\"100%\" style=\"border: none;\"></iframe>";
unlink("temp/".$name);
?>
Now the issue is that since the php script executes itself first and then echo's the buffer, the google viewer cannot find the file since its already deleted. Using flush() does not help either.
One work around is to remove the "unlink" command and create a cron-job to delete all files in the temp folder (say after every 2min). Is there a better way to do it?
I'd make the link to
echo "<iframe src=\"http://docs.google.com/viewer?url="http://www.domain.com/viewthis.php?name=abc.doc&embedded=true\" width=\"100%\" height=\"100%\" style=\"border: none;\"></iframe>";
then make viewthis.php stream the file... then as soon as it's served, you can delete it.
I assume (looking at the comment in line 2) that you are trying to view mail attachments. What you can do is dynamically create a file url for google to lookup the file. What you do is create a script, say 'view_file.php', which loads/downloads the file and pushes the file back, with some custom headers to tell the 'browser' (google) what kind of file it is. In this way you do not have to save the file. Downside is that the file will be accessible always from the outside, so you still should set a timer or something like that.
For an image you would do something like this:
$im = file_get_contents('http://www.site.com/url_to_your_image'); // or any other function to retrieve the image data itself
header('content-type: image/gif');
echo $im;
For any other file, just change the content-type header.
I am working on a simple document management system for a site - the user can upload around 20 different file types and the docs are renamed then stored in a folder above www, an entry is created in a docs table to capture meta data entered by the user and the item is then retrieved via another php file so the stored location for the files are hidden from the user.
When a user clicks to download a file using a simple a href it calls, for example, "view.php?doc=image.jpg" - when they do this currently the file opens in the browser so a jpg opens a window with pages of "wingdings" like characters etc.
I would like to be able to force a open/save dialogue box so the user decides what to do and my app doesn't try to open in the browser window with the above results.
From a previous posting I found I know I cannot pass the mime type in the "a href" tag so what other options do I have? Could I put header information into the below view.php file, for example?
$_file = $_GET['doc'];
$filename = './dir/'.$_file;
if (file_exists($filename)) {
echo file_get_contents('./dir/'.$_file);
} else {
echo "The file $_file does not exist";
}
;
You could use get_headers() to get the MIME type header of the desired file, and then use header() to output those headers into the file you're showing.
Alternatively, to simply force downloads, this:
header('Content-Description: File Transfer');
header("Content-type: application/octet-stream");
Should do it.
My site uses bookmarklets to gather data from external sites, kinda like Pinterest. I'm concerned about security and want to move the images the bookmarklet gathers from the doc root up one level. My script has some hefty security checks in place, but I want to add this as a last line of defense.
How do I access my images within my script? Obviously using ../userimages/id/image.jpg wont work. I'm using Apache.
Thanks!
Proxy the image
You would use a proxy script to feed the images through like the following example:
// open the file in a binary mode
$name = '../userimages/id/image.jpg';
$fp = fopen($name, 'rb');
// send the right headers
header("Content-Type: image/png");
header("Content-Length: " . filesize($name));
// you may like to set some cache headers here
// dump the picture and stop the script
fpassthru($fp);
exit;
This example is from the PHP manuals fpassthru() page. You would save this script somewhere in your servers document root/httpdocs folder.
"Spoofing" the URL to the image
The easiest way to give the PHP file the appearance of being an image file to a user/browser is to use Apaches mod_rewrite. Usually I use a URL structure something like this:
http://www.example.org/image-id/image.png
Where image-id is the unique identifier for that particular image. This way the file has the correct extensions of an image instead of .php.
I have a small script, which reads the data from DB, array them and save them as .txt file.
At the end, user is redirected to that file.
Now, how to achieve that when user is redirected on .txt file download box appears?
<?php
// Preden zacnemo, dobi novico iz baze!
$MOD_NEWS_SAVETXT_getnews = mysql_query("SELECT * FROM NEWS WHERE NEWSid = '{$_GET['id']}'") or die(mysql_error());
// Nardimo while in priredimo vsebino iz baze spremenljivkam!
while ($MOD_NEWS_SAVETXT_NEWSRESULT = mysql_fetch_array($MOD_NEWS_SAVETXT_getnews)) {
$MOD_NEWS_SAVETXT_FILE_name = $MOD_NEWS_SAVETXT_NEWSRESULT['NEWStitle'] . ".txt";
echo $MOD_NEWS_SAVETXT_FILE_name;
$MOD_NEWS_SAVETXT_FILE_handle = fopen($MOD_NEWS_SAVETXT_FILE_name, 'w') or die("Ne morem brati/ustvariti datoteke!");
fwrite($MOD_NEWS_SAVETXT_FILE_handle, $MOD_NEWS_SAVETXT_NEWSRESULT['NEWStext']);
fclose($MOD_NEWS_SAVETXT_FILE_handle);
header("Location: ./" . $MOD_NEWS_SAVETXT_FILE_name ."");
}
?>
This has come up before:
forcing a file to download
forcing a file download with php
How to Automatically Start a Download in PHP?
Correct way to trigger a file download (in PHP)?
To force a file to download, you have to send the HTTP Headers that will tell the browser to treat that file as a download. That is override the Content-Type of the file.
http://en.wikipedia.org/wiki/List_of_HTTP_headers
Basically, when your web server retrieves a file requested by the browser, it first checks the file extension and guesses the mime type. It then creates the HTTP response, and inserts the Content-Type header with the value of the mime-type it guessed.
You can have PHP set the content-type of the file explicitly.
The example is already given above.
header("Content-type: application/force-download");
or
header("Content-type: application/octet-stream");
For downloads, you also have to set the Content-Disposition and Content-Transfer-Encoding HTTP response headers.
These are defined in the MIME specifications: http://www.faqs.org/rfcs/rfc1521.html
It is also good to define the content-length as this allows the browser to give the user a download progress bar.
You may also want to look at using the range headers to allow request in parts.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html