Monday, 19 October 2009

Deleting a chosen file with PHP

I wanted a simple way to let users delete files already uploaded - and decided that I could create a form and populate it using PHP : one row per file, with a submit button each. The name of the submit button would be the file name. That way, when the form is submitted, I would get the key for the button pressed (each with value "Delete" so simply look for $_POST['Delete'], and delete that file.

Two snags worth noting:

First, PHP replaces a period OR a space with an underscore in field names submitted. so "abc def.pdf" appears in the $_POST array as "abc_def_pdf". The solution is to rawurlencode() the name and use this as the button name. Then when processing the $_POST field, use rawurldecode() - which still leaves the period as an underscore, so then run a replace function.


Secondly, there are lots of helpful scripts to show how to unlink, but none of them seemed to be clear on when a path is needed.
So if you write:
$handler = opendir($directory);
while ($fileName = readdir($handler)) {

the $filename variable will show just the filename - but when you come to
unlink($fileName);
it won't work - you need:
unlink($path.$fileName);

Example:


function modifyFileName($fileNameWithUnderscore) {
if (substr_count($fileNameWithUnderscore,"_") > 0) {
$lastPeriod = strrpos($fileNameWithUnderscore,"_");
$fileNameWithUnderscore = substr_replace($fileNameWithUnderscore,".",$lastPeriod,1);
}
return $fileNameWithUnderscore;
}


$hit=false;
$deletedOK=false;//default
foreach ($_POST as $key=>$value){
if ($value=="Delete"){
$encodedFileNameWithUnderscore=$key;
$hit=true;
}
}
if ($hit==true){
// create a handler for the directory
//$fileNameWithPeriod=modifyFileName($fileNameWithUnderscore);
$fileNameWithPeriod=modifyFileName(rawurldecode($encodedFileNameWithUnderscore));
$handler = opendir($directory);
// keep going until all files in directory have been read

while ($loopFileName = readdir($handler)) {
// if $file isn't this directory or its parent,
// delete it
if ($loopFileName != '.' && $loopFileName != '..'){
//echo $file;

//open and close to make sure it can be deleted
if ($loopFileName==$fileNameWithPeriod){
$fh = fopen($fileNameWithPeriod, 'w') or die("can't open file");
fclose($fh);
//delete the file
$deletedOK=unlink($directory.$fileNameWithPeriod);
}

} else {

}
}
// tidy up: close the handler
closedir($handler);
}

No comments: