phpdelete-file

Is it safe to delete an image after creating it with gs and displaying it this way in php?


EDIT 2 I moved the gs to the image php script. Now the file is created there and then deleted so there is no chance that a file will be left on the disk. The problem I had was that bots would read the main file without calling the image script thus the image file was not deleted. With the gs command in the image script, it works as it should. I just pass the file name and page number to the image script.


I am creating a png image from a pdf

gs -dNOPAUSE -dBATCH -r600 -dDownScaleFactor=3 -dFirstPage=11 -dLastPage=11 -sDEVICE=png16m -sOutputFile="xyzzy.png" myPDF.pdf

Then I display it and call a php image file that deletes the image after a delay

<img src='xyzzy_png'>
<img src="delete_img.php" width="0" height="0" border="0" alt="">

delete_img.php looks like this

 <?header('Content-type:image/png');
 include("php8sucks.php");
 $key = get_num('n');
 $file = 'xyzzy' . $key . '.png';
 readfile($file);
 usleep(100000);
 unlink($file);
 exit;
 ?>

Is this safe? How can it fail? I have tested it and can see the file come and go on my server. Even if I close the main file, after the sleep time the image file is removed.

I should add, I tried several other suggestions on SO that did not work. There are others I have not tried that involve having some script that does house cleaning periodically. That would probably work but I worry about a bot loading a huge number of files and overloading the server space. I would rather clean up as I go.

The situation I am in is that there are lots of potential files for all the possible pdf conversions and I need to increase the resolution. That would just use too much server space so I can't leave all the potential files lying around.

What other conditions should I test? Anything I am overlooking?

What is a safe delay? I have tested 5 seconds and 60 seconds. Both seem to work. I have not tested multiple versions of my delete_img.php file running but of course I would use different file names for different files.

I will note that including the delete_img.php file rather than calling it does not work. This is the only way I could think of calling the file without including it. The zero size image does not show up on in Chrome or Firefox. I have not tried other browsers.

I clearly need to make sure the delete_img.php file cannot delete any old file on my server. It is hard coded for testing but eventually it would have some kind of safety to only delete specific files. I am thinking file names like 'filennnn.png where the nnnn is a random number and it the only thing passed to the delete_img.php file.

=====EDIT============= The suggested solution isn't working. The files display just fine but the original image is not being deleted. The call to this function is a 10 digit random number defining the file. That way there can't be any conflicts with two users getting the same filename.

I implemented the delete_img.php funtion like this

<?header('Content-type:image/png');
include("php8sucks.php");
$file = get_num('n');
$file2 = 'xyzzy' . $file . '.png';
readfile($file2);
unlink($file2);
exit;
?>

php8sucks has this function in it

function get_num($num){
    if(isset($_GET[$num])){
        $s = val_num($_GET[$num]);
    }   
    else $s = 0;
    return $s;
}

I am not sure what it going on. I will see if a delay will help. Perhaps it is a timing issue. For now, I will delete the files manually. Perhaps I will end up with a cron job afterall.


Solution

  • The sleep(5) makes it unlikely to fail. But a better way would be to use a single script to fetch the image and delete it.

    <?php
    header('Content-type: image/png');
    readfile('xyzzy.png');
    unlink('xyzzy.png');
    

    You should also move the image file out of the web root, so it can only be fetched through the script that deletes it.