How do I Retrieve -> View -> Delete File in PHP? - php

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.

Related

PHP: set image as background without revealing path

The following problem I can't really wrap my mind around, so really if you guys can't be bothered to supply the entire code some tips leading in the right direction would be great!
So, I have a script where users can upload images to a server. PHP takes care of validating the file and saving it using a new filename in another folder, neither known by the client. Now, the client should be able to see the uploaded image, in html simply:
style="background-image:url('testimagegif.gif');
But preferably the client should not be able to see the path nor the file name of the image saved on the server. I know about using header('Content-type: ... for forcing the client browser to download files, but I do not see how this, nor any similar solution could be applied to this case. Same goes for readfile. If I use it the browser simply downloads the image, not placing it in the html.
You should probably be moving the files into a publicly readable folder on your webserver if you want to serve them.
Otherwise, you'll need something like readfile()
There are two options for this, you could use the data protocol, which would embed the whole image into the URL of the background ( this isn't recommended if the image is bigger than a few kb. ) or you can use a script to present the image by encoding or recording a unique key for the image, eg bg.php?id=4323-34442-3432-4532 which checks a db for the id to retrieve the file path then echoes the content with the right content type.
Some examples;
based on the Data URI wikipedia page
Data URI Method
Assuming a function like this;
function data_uri($fileID) {
$fRecord = mysql_fetch_array(
mysql_select("SELECT filePath, mimeType from fileTable WHERE fileID = " $fileID . ";")
);
$contents = file_get_contents($fRecord['filePath']);
$base64 = base64_encode($contents);
return "data:$fRecord['mimeType'];base64,$base64";
}
Then in your html/php page you'd have the following snippet
style="background-image:url('<?php echo data_uri($fileID);?>'
PHP Image Dump
Assuming a function like this;
// Given a filename and a mimetype; dump the contents to the screen
function showDocumentContent($fileID){
$fRecord = mysql_fetch_array(
mysql_select("SELECT filePath, mimeType from fileTable WHERE fileID = " $fileID . ";")
);
header( 'Content-Encoding: none', true );
header( 'Content-Type: ' . $fRecord['mimeType'], true );
echo readfile( $fRecord['filePath'] );
}
Then in your html page you'd have this;
style="background-image:url('image.php?fileID=123')
In the first case, images larger than a few KB will result in equally large HTML pages, and may not be supported in browsers consistently. In the second case, you'd effectively have created a php script that is pretending to be an image. In both cases, the real path to the binary files on your server is abstracted away by storing a mapping in a database.
If you store the paths to the files somewhere like a database or a file, you can use readfile() to output the file once you retrieve the path.
Combine that with the content-type header, and set the background-image URL to the PHP script with the correct query string like so:
style="background-image:url('script.php?img=30382');"
You must expose some path to the client, because their browser has to access the file. You can use your webserver config to serve at an indirected location, or serve the image with PHP and have the real path in a call to readfile()

Clean up after creating the pdf

I'm generating a pdf file with html2fpdf.
$pdf = new HTML2FPDF();
$pdf->HTML2FPDF("P","mm","A4");
$pdf->AddPage();
$pdf->WriteHTML($html);
$pdf->output('sample.pdf');
This sample works great. But:
How do I delete the pdf after the output? I just want to have links in my tool, the users can download the pdf and after that it shoud be deleted on the server.
How can I 'clean up' after generating the pdf?
You can use PHP's file deletion function called unlink()
Call this function with the full path to the generated PDF file (or any file for that matter) and PHP will delete that file.
http://php.net/manual/en/function.unlink.php
You don't necessarily have to delete the file immediately after the user has downloaded it. You can just as easily place all the generated files in one central folder and have a cron job execute a more general clean up script simply removing the older files.
One method could be -
Scan the contents of the folder using scandir().
Iterate over its files in a foreach loop..
Inspect the creation time of each file using filemtime().
If the creation time was over hour ago, delete the file using unlink().
Because you are generating the PDF file yourself within your PHP code, I didn't mention the permissions consideration. Here would be a good place to mention that your PHP must have the correct file system permissions in order to perform any action on the file system. You are creating a PDF file so it's safe to assume that you have the correct permissions to make changes to the file system but if you plan on using this unlink() function in other scripts make sure that the files you are dealing with have the correct permissions set.
If you don't add the 'F' flag to the output function there will be no pdf files stored on the server at all:
$pdf->output('sample.pdf', 'F'); //stores PDF on server
In your case the script itself behaves like an actual pdf file. So, creating a link to the script is just like a link to the pdf, except that the PDF is created every time the script is requested. To tell the browser it's a PDF the content-type response header must be set to application/pdf:
content-type: application/pdf
This way the broser knows that it's a pdf even if the URL is ending in a .php. You can use rewrite engine to make it end in pdf or whatever else.
Sending the headers is done by the fpdf/tcpdf. In short: you don't have to do any cleanup, because no pdf file is stored on the server.
If you wonder what the name is for than, try saving the pdf file. The recommanded name when saving will be sample.pdf.
Reference:
PHP header() function, at the examples there is one for sending pdf
FPDF::Output()
TCPDF::Output()

Moving images from doc root for added security

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.

PHP - List of Excel files to download from Intranet Site?

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.

How to save a snapshot of a SWF to the server with AS3?

I am facing the task of having to upload a snapshot to the server. But I don't want the user to download the image to their computer.
I have explored a few solutions of generating an image serverside with PHP, but they all seem to use a method where the server sends the image to the user.
See for instance: http://mattkenefick.com/blog/2008/11/06/saving-jpegs-with-flash/
I'm wondering if it's possible to save $GLOBALS["HTTP_RAW_POST_DATA"], which in that example contains the ByteArray sent by Flash, to the server as an image file....
Use php code that is along these lines to save the contents of $GLOBALS["HTTP_RAW_POST_DATA"]
// untested code
$imageBytes = $GLOBALS["HTTP_RAW_POST_DATA"]
// in real code you better create a new file for every upload :-)
$file = fopen("uploads/test.jpg", "w");
if(!fwrite($file, $imageBytes)){
return "Error writing to file: $file";
}
fclose($file);

Categories