(PHP 4, PHP 5)
unlink — Löscht eine Datei
Löscht filename. Ähnlich der UNIX-C-unlink()-Funktion. Ein E_WARNING-Fehler wird im Fehlerfall generiert.
Pfad zur Datei.
Hinweis: Die Kontext-Unterstützung gibt es seit PHP 5.0.0. Eine Beschreibung von Kontexten finden Sie unter Stream Funktionen.
Gibt bei Erfolg TRUE zurück. Im Fehlerfall wird FALSE zurückgegeben.
| Version | Beschreibung | 
|---|---|
| 5.0.0 | Seit PHP 5.0.0 kann unlink() auch mit einigen URL-Wrappern genutzt werden. In der Supported Protocols and Wrappers finden Sie eine Liste aller Wrapper, die unlink() unterstützen. | 
Beispiel #1 Einfache Nutzung von unlink()
<?php
$fh = fopen('test.html', 'a');
fwrite($fh, '<h1>Hallo Welt!</h1>');
fclose($fh);
unlink('test.html');
?>
Deleted a large file but seeing no increase in free space or decrease of disk usage? Using UNIX or other POSIX OS?
The unlink() is not about removing file, it's about removing a file name. The manpage says: ``unlink - delete a name and possibly the file it refers to''.
Most of the time a file has just one name -- removing it will also remove (free, deallocate) the `body' of file (with one caveat, see below). That's the simple, usual case.
However, it's perfectly fine for a file to have several names (see the link() function), in the same or different directories. All the names will refer to the file body and `keep it alive', so to say. Only when all the names are removed, the body of file actually is freed.
The caveat:
A file's body may *also* be `kept alive' (still using diskspace) by a process holding the file open. The body will not be deallocated (will not free disk space) as long as the process holds it open. In fact, there's a fancy way of resurrecting a file removed by a mistake but still held open by a process...
Here the simplest way to delete files with mask
<?php
   $mask = "*.jpg"
   array_map( "unlink", glob( $mask ) );
?>
a note to the windows unlink problem. I had some code running on a linux server, unlinking files fine, but when i switched to my home computer running on windows, i suddenly had the unlink - permission denied problem. After trying everything (all those things with ownership, etc.), i found out that my file (a temporary file created with tempnam) was not closed, therefore it couldn't be unlinked. I hope this helps someone outthere :)
unlink can fail after using ODBC commands on the file (on Windows).
Neither <?php odbc_free_result($result); ?> nor <?php odbc_close($conn); unset($conn); ?> did the trick.
Only <?php odbc_close_all(); ?> released the file such that it could be deleted afterwards ...
Shorter'n'faster version of Eddys "The shortest recursive delete possible"
function rrmdir($path)
{
  return is_file($path)?
    @unlink($path):
    array_map('rrmdir',glob($path.'/*'))==@rmdir($path)
  ;
}
May sound dumb, but it may help. Permission denied? Is the file still open in your script? Was for me...
If you're using PHP >= 5.0, consider using RecursiveDirectoryIterator (http://php.net/manual/en/class.recursivedirectoryiterator.php) class to iterate over all directories and files in a subtree in order to remove them.
Just be sure to use ->isDot() (http://php.net/manual/en/directoryiterator.isdir.php) to check for, and skip, dot and dot-dot (`.' and `..') directories :P
The shortest recursive delete possible.
<?php
    /**
     * Delete a file or recursively delete a directory
     *
     * @param string $str Path to file or directory
     */
    function recursiveDelete($str){
        if(is_file($str)){
            return @unlink($str);
        }
        elseif(is_dir($str)){
            $scan = glob(rtrim($str,'/').'/*');
            foreach($scan as $index=>$path){
                recursiveDelete($path);
            }
            return @rmdir($str);
        }
    }
?>
careful with unlink...
"very unlikely" is not "impossible" : granted, it will happen.
1) "expected" : a typo and you'll get : unlink('/')
2) "very likely" : some of your files are writeable by anyone. 
3) "possible" : you're backup drive is mounted and preserves the authorizations of the original files
4) "very unlikely" : that particular day, at that particular moment, the unlink function decided to work recursively
played all day long with ext3grep : no result.
Here is the recursive delete method made a little more readable:
<?php
/**
 * Recursively delete a directory
 *
 * @param string $dir Directory name
 * @param boolean $deleteRootToo Delete specified top-level directory as well
 */
function unlinkRecursive($dir, $deleteRootToo)
{
    if(!$dh = @opendir($dir))
    {
        return;
    }
    while (false !== ($obj = readdir($dh)))
    {
        if($obj == '.' || $obj == '..')
        {
            continue;
        }
        if (!@unlink($dir . '/' . $obj))
        {
            unlinkRecursive($dir.'/'.$obj, true);
        }
    }
    closedir($dh);
    
    if ($deleteRootToo)
    {
        @rmdir($dir);
    }
    
    return;
}
?>
To unlink, the web server user must have write permissions to the directory.
Conversely, if a user has write permissions to a directory, it may delete files from that directory regardless of who owns them...
using this function with windows will generate an error, make sure to use is_file
When I'm using unlink() or rename() with a SSH2.SFTP wrapper, both functions always return FALSE (but without a warning) even on success.
Example:
<?php
$connection = ssh2_connect(SERVER_NAME, PORT);
ssh2_auth_password($connection, USERNAME, PASSWORD);
$sftp = ssh2_sftp($connection);
unlink("ssh2.sftp://$sftp/" . REMOTE_DIRECTORY . FILENAME); // returns FALSE on success and on failure
rename("ssh2.sftp://$sftp/" . REMOTE_DIRECTORY . OLD_FILENAME, "ssh2.sftp://$sftp/" . REMOTE_DIRECTORY . NEW_FILENAME); // returns FALSE on success and on failure
?>
Under Windows System and Apache, denied access to file is an usual error to unlink file.
To delete file you must to change file's owern.
An example:
<?php
chown($TempDirectory."/".$FileName,666); //Insert an Invalid UserId to set to Nobody Owern; 666 is my standard for "Nobody"
unlink($TempDirectory."/".$FileName);
?>
To anyone who's had a problem with the permissions denied error, it's sometimes caused when you try to delete a file that's in a folder higher in the hierarchy to your working directory (i.e. when trying to delete a path that starts with "../").
So to work around this problem, you can use chdir() to change the working directory to the folder where the file you want to unlink is located.
<?php
    $old = getcwd(); // Save the current directory
    chdir($path_to_file);
    unlink($filename);
    chdir($old); // Restore the old working directory    
?>
This is in response to alvaro at demogracia dot com
Yes, I found that out and have had to wrap it with is_file:
<?php
if(is_file("$file")) {
unlink("$file");
}
?>
I have been working on some little tryout where a backup file was created before modifying the main textfile. Then when an error is thrown, the main file will be deleted (unlinked) and the backup file is returned instead.
Though, I have been breaking my head for about an hour on why I couldn't get my persmissions right to unlink the main file.
Finally I knew what was wrong: because I was working on the file and hadn't yet closed the file, it was still in use and ofcourse couldn't be deleted :)
So I thought of mentoining this here, to avoid others of making the same mistake:
<?php
// First close the file
fclose($fp);
// Then unlink :)
unlink($somefile);
?>
I have founda that trying to delete a file using relative path like the example below does not work.
<?php
    $do = unlink("../pics/$fileToDel");
    if($do=="1"){
        echo "The file was deleted successfully.";
    } else { echo "There was an error trying to delete the file."; } 
?>
I did not work at all, instead what I had to do was: 
<?php
    chdir('../pics/');
    $do = unlink($fileToDel);
    if($do=="1"){
        echo "The file was deleted successfully.";
    } else { echo "There was an error trying to delete the file."; }
?>
Then it worked !
ggarciaa's post above has already one small error, closedir has to be used even if $DeleteMe is false
<?php
// ggarciaa at gmail dot com (04-July-2007 01:57)
// I needed to empty a directory, but keeping it
// so I slightly modified the contribution from
// stefano at takys dot it (28-Dec-2005 11:57)
// A short but powerfull recursive function
// that works also if the dirs contain hidden files
//
// $dir = the target directory
// $DeleteMe = if true delete also $dir, if false leave it alone
function SureRemoveDir($dir, $DeleteMe) {
    if(!$dh = @opendir($dir)) return;
    while (false !== ($obj = readdir($dh))) {
        if($obj=='.' || $obj=='..') continue;
        if (!@unlink($dir.'/'.$obj)) SureRemoveDir($dir.'/'.$obj, true);
    }
    closedir($dh);
    if ($DeleteMe){
        @rmdir($dir);
    }
}
//SureRemoveDir('EmptyMe', false);
//SureRemoveDir('RemoveMe', true);
?>
Cheap and dirty example for cleaning a directory of files so many seconds old.
        function cleantmp() {
                $seconds_old = 3600;
                $directory = "/var/tmp";
                if( !$dirhandle = @opendir($directory) )
                        return;
                while( false !== ($filename = readdir($dirhandle)) ) {
                        if( $filename != "." && $filename != ".." ) {
                                $filename = $directory. "/". $filename;
                                if( @filemtime($filename) < (time()-$seconds_old) )
                                        @unlink($filename);
                        }
                }
        }
ggarciaa's post above has one small error, it will ignore file and directory strings that are evaluated as false (ie. "0")
Fixed code is below (false !==)
<?php
// ggarciaa at gmail dot com (04-July-2007 01:57)
// I needed to empty a directory, but keeping it
// so I slightly modified the contribution from
// stefano at takys dot it (28-Dec-2005 11:57)
// A short but powerfull recursive function
// that works also if the dirs contain hidden files
//
// $dir = the target directory
// $DeleteMe = if true delete also $dir, if false leave it alone
function SureRemoveDir($dir, $DeleteMe) {
    if(!$dh = @opendir($dir)) return;
    while (false !== ($obj = readdir($dh))) {
        if($obj=='.' || $obj=='..') continue;
        if (!@unlink($dir.'/'.$obj)) SureRemoveDir($dir.'/'.$obj, true);
    }
    if ($DeleteMe){
        closedir($dh);
        @rmdir($dir);
    }
}
//SureRemoveDir('EmptyMe', false);
//SureRemoveDir('RemoveMe', true);
?>
<?php
// ggarciaa at gmail dot com (04-July-2007 01:57)
// I needed to empty a directory, but keeping it
// so I slightly modified the contribution from
// stefano at takys dot it (28-Dec-2005 11:57)
// A short but powerfull recursive function
// that works also if the dirs contain hidden files
//
// $dir = the target directory
// $DeleteMe = if true delete also $dir, if false leave it alone
function SureRemoveDir($dir, $DeleteMe) {
    if(!$dh = @opendir($dir)) return;
    while (($obj = readdir($dh))) {
        if($obj=='.' || $obj=='..') continue;
        if (!@unlink($dir.'/'.$obj)) SureRemoveDir($dir.'/'.$obj, true);
    }
    if ($DeleteMe){
        closedir($dh);
        @rmdir($dir);
    }
}
//SureRemoveDir('EmptyMe', false);
//SureRemoveDir('RemoveMe', true);
?>
Here is simple function that will find and remove all files (except "." ones) that match the expression ($match, "*" as wildcard) under starting directory ($path) and all other directories under it.
function rfr($path,$match){
   static $deld = 0, $dsize = 0;
   $dirs = glob($path."*");
   $files = glob($path.$match);
   foreach($files as $file){
      if(is_file($file)){
         $dsize += filesize($file);
         unlink($file);
         $deld++;
      }
   }
   foreach($dirs as $dir){
      if(is_dir($dir)){
         $dir = basename($dir) . "/";
         rfr($path.$dir,$match);
      }
   }
   return "$deld files deleted with a total size of $dsize bytes";
}
<?php
$myFile = "testFile.txt";
$fh = fopen($myFile, 'w') or die("can't open file");
fclose($fh);
?>
Now to delete testFile.txt we simply run a PHP script that is located in the same directory. Unlink just needs to know the name of the file to start working its destructive magic.
<?php
$myFile = "testFile.txt";
unlink($myFile);
?>
The testFile.txt should now be removed.
A work around for the Permission Denied problem.
I used ftp_connect() then ftp_delete() to erase files which unlink could not erase due to permision problems
<?php
/**
 * rm() -- Vigorously erase files and directories.
 * 
 * @param $fileglob mixed If string, must be a file name (foo.txt), glob pattern (*.txt), or directory name.
 *                        If array, must be an array of file names, glob patterns, or directories.
 */
function rm($fileglob)
{
    if (is_string($fileglob)) {
        if (is_file($fileglob)) {
            return unlink($fileglob);
        } else if (is_dir($fileglob)) {
            $ok = rm("$fileglob/*");
            if (! $ok) {
                return false;
            }
            return rmdir($fileglob);
        } else {
            $matching = glob($fileglob);
            if ($matching === false) {
                trigger_error(sprintf('No files match supplied glob %s', $fileglob), E_USER_WARNING);
                return false;
            }       
            $rcs = array_map('rm', $matching);
            if (in_array(false, $rcs)) {
                return false;
            }
        }       
    } else if (is_array($fileglob)) {
        $rcs = array_map('rm', $fileglob);
        if (in_array(false, $rcs)) {
            return false;
        }
    } else {
        trigger_error('Param #1 must be filename or glob pattern, or array of filenames or glob patterns', E_USER_ERROR);
        return false;
    }
    return true;
}
?>
[Editor's note: A suggestion for a work-around was submitted by argistof at gmail dot com: You can use the recursive option (see man chmod) when chmodding, for instance 'chmod 777 directory/ -R'. Be aware though, this will change the permissions of all files and folders in the diectory.]
Just a note which you probably all know, but I didn't, and it might save another poor sap some unnecessary time:
I was doing unlink() and fopen() on a file and got a permission denied error, even after chmoding the file to 0777.  
The folder that contains the file must ALSO have write permission.  Took a headache to find this out.  
Hope this helps someone :)
Actually you should use "@unlink" rather than testing with file_exists. The former is atomic, whereas the latter can break if you can't guarantee only one process will try to delete a given file at a time.
before you could unlink a file created which uses a handle e.g., 
$handle = sqlite('temp.db'); 
unset($handle); first befofe
unlink($handle);
to avoide permission denied error.
To delete all files of a particular extension, or infact, delete all with wildcard, a much simplar way is to use the glob function.  Say I wanted to delete all jpgs .........
<?php
foreach (glob("*.jpg") as $filename) {
   echo "$filename size " . filesize($filename) . "\n";
   unlink($filename);
}
?>
To delete files using wildcards:
<?
function delfile($str)
{
    foreach(glob($str) as $fn) {
        unlink($fn);
    }
}
?>