Processing a local file from a server - php

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.

Related

How Do I Set PHP to Download database to D drive?

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.

Webpages not served during large file transfers (IIS7.5 + PHP)

For some reason, our webserver is not responding while it's serving large files.
We use the windows platform, because we need to remotely call Win32 applications in order to generate the file that is to be served. This file is served through PHP's function: fpassthru, using this code:
if (file_exists($file)) {
$handle = #fopen($file, "rb");
header('Content-Description: File Transfer');
header('Content-Type: video/mp4');
if($stream==0){
header('Content-Disposition: attachment; filename='.basename($filename.".mp4"));
}
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_end_clean();
fpassthru($handle);
exit;
}
These files are often over 1GB in size and takes a while to transfer, but during this time, the webserver will not serve any pages. My firefox indicates it's 'connecting' but nothing else. Note that somebody else is transferring this file, not me, so different IP, different session.
Any clue where to look? Obviously, it's intolerable to have to wait 5 minutes for a website.
Thanks in advance!
This is commonly caused when you do not close the session before you begin sending the file data. This is because the session cache file can only be opened by one PHP process at a time, therefore the download is effectively blocking all other PHP processes at session_start().
The solution is to call session_write_close() to commit the session data to disk and close the file handle before you start outputting the file data.

Using JavaScript and PHP to download image files and return a zip file

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;

Open/save PDF located in server folder

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)

how do you support seeking of an mp3 when returning from a php script?

I have an mp3 on my server (urls are just examples):
http://www.my-server.com/myaudio.mp3
I have a php script on the server at:
http://www.my-server.com/testmp3.php
Which contains the following code (which I got here):
<?
$file = "myaudio.mp3";
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, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
?>
Is this all I have to do to mimic the behavior so that both request behave the same way and return the exact same response? Or is there anything I'm missing.
I'm using some streaming code on iOS (not relevant here) and both requests stream the audio fine but I can't seek properly using the php request but I can with the mp3 request directly.
So without getting into details about the app itself I wanted to eliminate this one variable first. Is there anything I need to do to make sure that from another app's perspective these two request will return the exact same data?
Thanks for any input you can give me here.
Update
It turns out my question really should have read "how do you support seeking of an mp3 when returning from a php script?".
To support seeking, you often will have to support a range request.
From the RFC: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35
See also: Resumable downloads when using PHP to send the file?
Its probably better to handle this with a .htaccess modification rather than some PHP code.
Here's a link on htaccess to get you started.
If you have a whole directory of .mp3 files that you want to appear as downloads instead of playing it in browser, you'd simply modify the .htaccess file in that folder to include
AddType application/octet-stream .mp3

Categories