PHP Doku:: Löscht eine Datei - function.unlink.html

Verlauf / Chronik / History: (8) anzeigen

Sie sind hier:
Doku-StartseitePHP-HandbuchFunktionsreferenzDateisystemrelevante ErweiterungenDateisystemDateisystem-Funktionenunlink

Ein Service von Reinhard Neidl - Webprogrammierung.

Dateisystem-Funktionen

<<umask

Inotify>>


31 BenutzerBeiträge:
- Beiträge aktualisieren...
dexen dot devries at gmail dot com
31.12.2010 10:28
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...
federico at poisonfx dot com
6.12.2010 11:55
Here the simplest way to delete files with mask

<?php
   $mask
= "*.jpg"
  
array_map( "unlink", glob( $mask ) );
?>
kgy
25.11.2010 23:34
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 :)
lpatrick
25.10.2010 11:08
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 ...
zibi at nora dot pl
24.09.2010 16:01
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)
  ;
}
layla_mwazza at hotmail dot com
12.07.2010 19:02
May sound dumb, but it may help. Permission denied? Is the file still open in your script? Was for me...
mateusz at bkfmyjnie dot pl
6.05.2010 10:08
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
Eddy Vlad
24.11.2009 5:59
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);
        }
    }
?>
reminder
12.06.2009 23:24
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.
Jon Hassall
16.11.2008 19:36
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;
}
?>
Anonymous
1.11.2008 15:13
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...
hi at hi dot hi
12.10.2008 5:19
using this function with windows will generate an error, make sure to use is_file
garagod at gmail dot com
6.10.2008 19:36
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
?>
http://www.paladinux.net
1.10.2008 17:59
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);
?>
gotdalife at gmail dot com
25.09.2008 16:04
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   
?>
southsentry at yahoo dot com
31.08.2008 19:23
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");
}
?>
PD
6.08.2008 14:07
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);
?>
Guilherme Komel
30.12.2007 1:14
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 !
ayor ATTTTT ayor.biz
20.12.2007 15:02
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);

?>
james at NOSPAM dot telserco dot com
29.09.2007 16:10
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);
                        }
                }
        }
rahulnvaidya at gmail dot com
3.08.2007 11:36
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);

?>
ggarciaa at gmail dot com
4.07.2007 8:00
<?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);

?>
torch at torchsdomain dot com
22.11.2006 21:27
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";
}
bmcouto at hotmail dot com
30.09.2006 22:30
<?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.
paul at pes-systems dot net
16.08.2006 19:27
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
bishop
5.06.2005 21:30
<?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;
}
?>
jchase at solidmark dot com
21.05.2005 7:05
[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 :)
ashley at semantic dot org
2.04.2005 12:50
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.
dagski_AT_gmail_DOT_com
7.02.2005 7:19
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.
chris at vibenewmedia dot com
14.09.2004 19:54
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);
}

?>
pc AT newagelab DOT com DOT ua
8.09.2004 17:22
To delete files using wildcards:

<?
function delfile($str)
{
    foreach(
glob($str) as $fn) {
       
unlink($fn);
    }
}
?>



PHP Powered Diese Seite bei php.net
The PHP manual text and comments are covered by the Creative Commons Attribution 3.0 License © the PHP Documentation Group - Impressum - mail("TO:Reinhard Neidl",...)