I want to give to the users of a PHP intranet the possibility to open/save PDF files, which are located in a folder on the Apache server. The PDFs have company private information, so I don't want to put them in a web folder.
echo '<form name="openpdf" method="POST" action="downloadPDF.php">';
echo '<input type="hidden" name="pdf">';
echo'</form>';
<tr>
<td> PDFFile1 </td>
<td></td></tr>
downloadPDF.php:
<?
$pdf=$_POST["pdf"];
if (file_exists($pdf)) {
header('Content-Description: File Transfer');
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename='.basename($pdf));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($pdf));
ob_clean();
flush();
readfile($pdf);
exit;
}
?>
The problem is when the user open/save a file, the path is pointing for that folder but in the client PC and not at the server.
If you process the PDFs internally on the server from PHP, you should omit the file:/// from the URL.
So it should be
$pdf="c:/pdfs/example.pdf";
The server does not know the client PC, so readfile does not work here.
You might want to try with a redirect, but I must admit I have no clue if browsers allow that for security reasons (you're switching protocols with the redirect).
What at the moment you are doing is that
Javascript is putting a value of c:\pdfs\example.pdf in the pdf field of your form on click and submitting it to downloadpdf.php.
On server, Downloadpdf.php is assigning $_POST["pdf"] value to $pdf.
If file $pdf exists, it is simply proceeding to offer user to download this file.
Now, this may work where server & client is same computer(specifically on a PC, because of C: drive); i.e. like on Local XAMPP. But on real world, where user and server will be on totally different computers, the if (file_exists($pdf)) is always going to fail(unless On server's C: actually there is a file exaple.pdf in folder pdfs)
In real world, step 3 will fail, because $pdf = c:\pdfs\example.pdf and server will look into its own C: drive (if it is a windows server).
You should
1 Try to upload file with an HTML File Upload Box.
2 Get/fetch it on server using $_FILES and do processing
3. Send required headers for downloading.
For further information, please see HTML Form File Upload (Google) & $_FILES (PHP.Net)
Related
I am using below php to open pdf, it is working in Windows browser (eg. Windows Google Chrome), but failure to open by Mobile App (eg: Android Google Chrome), it will be download instead of open.
<?php
$com_no = $_POST['comno'];
$date = $_POST["date"];
$name_of_doc = $_POST["name_of_doc"];
// Store the file name into variable
$file = $com_no.'.pdf';
$filename = $date."_".$name_of_doc;
// Header content type
header('Content-type: application/pdf');
header('Content-disposition: inline; filename="'.$filename.'.pdf"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
// Read the file
#readfile($file);
?>
How shoule I rewrite it to support both open in the Windows and Mobile ?
Thank you very much !
TLDR: you can't program it as it is a browser configuration
If your PDF is opened in your desktop browser you have a configuration in your desktop-browser how to handle files of this type.
By default your browser should ask you what to do with data of that mime type.
You get the option:
open with browser
open with other application
store file
and maybe an option
[ ] always perform this action for files of this type
once you checked the option you no longer get bothered.
BTW:
even if you select open in browser, the file is downloaded in a temp folder to get shown.
i have a files for download mysql database using php.which is working properly.but i want to download codes to specific folder created in D drive
$backup_file_name = $database_name . '_backup_' . time() . '.sql';
$fileHandler = fopen($backup_file_name, 'w+');
$number_of_lines = fwrite($fileHandler, $sqlScript);
fclose($fileHandler);
// Download the SQL backup file to the browser
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($backup_file_name));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($backup_file_name));
file_put_contents('D:\dbbackups', $backup_file_name);
ob_clean();
flush();
readfile($backup_file_name);
exec('rm ' . $backup_file_name);
but file id download inside the project folder.any help would be highly appreciated
From PHP, you can't.
Your server-side PHP application has no knowledge of, or control over, the application or device which is making the HTTP request. All it does it return some data and headers to the requesting client.
Your server / PHP has no idea whether
the client device even has a D: drive (or even runs an O/S which uses drive letters), or whether a specific folder exists within it
the client will even treat the response as a file and try to save it somewhere
And even if it did know the above, then
your server would have no permissions to access the client-side device or its storage media.
If what you're suggesting was possible it would be a big security / privacy problem. But it would still be impractical even then, because of my first point.
What you can do to help yourself in this situation though is to write your own client-side program which makes the HTTP request to your server to execute the PHP, receives the data in the response and saves it to the location you want. Or if you're doing this via a browser you can set the browser's default download location to that folder.
I have these PHP headers that will force a download (Intranet site) that works on Chrome without prompting the popup, but I cannot avoid the popup warning in Internet Explorer 11 (Version 11.657.18362.0) on Windows 10.
I've tried adding to IE "intranet" site and "internet" site the internal server address this would run from (http://[server]), lower the security levels to the lowest settings for this zone under "intranet" and also "internet". Close and open Internet Explorer and it still has the popup warning.
Here is my PHP code below:
if ($_REQUEST['c']){
$num = $_REQUEST['c'];
$cmd = "test.exe $num";
$ctype ="application/octet-stream";
ob_end_clean();
header('Content-Description: File Transfer');
header('Content-Type:' . $ctype);
header('Content-Disposition: attachment; filename="test.bat"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: no-cache, must-revalidate');
header('Pragma: public');
header('Content-Length: ' . strlen($cmd));
echo($cmd);
exit;
}
Additionally, once the bat file has downloaded, there is a separate AutoIt script on the user's computer that will scan the download folder for this specific file and will automatically run the file and delete it without the user having to do anything. The idea is to limit the user's clicking to just one time.
This is the popup that I get from IE when I click to download the bat file below:
Any ideas what's wrong or other suggestions around this?
I'm able to reproduce the problem, but it seems that IE browser will keep display this prompt when downloading the bat file for security reason, and we can't disable it.
As a workaround, I suggest you could convert the bat file to a ZIP file, and then download it. Here are some related threads about how to Zip files using JavaScript, you could check them:
How to create zip files using javascript?
How to Zip files using JavaScript?
I have a PHP script that is currently working locally that I'd like to put on a server.
Currently, the user choose a .txt file, the PHP script works on it and outputs a new file based on what it read in the file.
The problem is that I can only select files in the folder with the script, and not elsewhere.
I use a to get the file name, but it only gives out the name of the file, and not it's absolute path.
From what I've read, I think that I need to upload the file to the server, process it with the script and then give it back to the user.
I'm not sure this is the correct method though.
Also, while I have found plenty of informations on uploading files to the server, I don't know how to put the new file created by the script in the folder where the original file is located.
You cannot read or write files directly on the client's machine. The client will need to upload the file by selecting it in the browser, the server receives the data, processes the data and returns data. This returned data can be presented in the form of a file download by setting the appropriate HTTP headers. The client will have to acknowledge the file download and save it somewhere of his choosing.
Your server has no business knowing anything about files or folders on the client's machine. It can only communicate with it over the HTTP protocol and send and receive data.
You will have to give the file back to the client, as a downloadable file. You can "write" it to the user by setting some headers. Take a look:
<?php
$file = 'random_text_file.txt';
if (file_exists($file)) {
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');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
?>
That will prompt a download of the file to the user.
I'm in the middle of developing a Safari extension for imageboard-type websites and one of the bigger features I'm hoping to implement is the ability to download all of the images (the posted ones, not the global page-level images) that had been posted.
There are similar questions here already, but mine differs a bit in that the images in question are hosted on an entirely different server. I've been brainstorming a bit and figured that gathering all of the image URLs in a JS array then sending it to my server to be turned into a zip file (forcing the download, not just a link to the file) would be the best way to go. I also want the zip to be deleted after the user downloads it.
I've already finished the majority of the extension features but this one is stumping me. Any help would be greatly appreciated.
How would I'd go about doing this?
You want a extension to contact your server for downloads? That's a terrible idea! Make the zipfile locally - it's not regular javascript, it's an extension - you have full access.
Anyway assuming you want to do this anyway, what is the trouble you are having? You get a list of urls, send them to your server, your server downloads them, zips them and send them to the user. (The "your server downloads them" part should worry you!)
What problem are you having?
You can use PHP's ZipArchive class to make a ZIP, then stream it to the browser.
<?php
// Create temp zip file
$zip = new ZipArchive;
$temp = tempnam(sys_get_temp_dir(), 'zip');
$zip->open($temp);
// Add files
$zip->addFromString('file.jpg', file_get_contents('http://path/to/file.jpg'));
$zip->addFile('/this/is/my/file.txt');
// Write temp file
$zip->close();
// Stream file to browser
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=myFile.zip');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($temp));
readfile($temp);
unlink($temp);
exit;