Php unlink не удаляет файл
не подавлять ошибки с @ , его редко целесообразно.
можете ли вы быть более описательным о @
Я не уверен, что вы имеете в виду именно. Но документация здесь. Почему ты не хочешь его использовать. Потому что тогда вы никогда не знаете, что код не работает или проблематично. Даже если код все еще работает с функциональной точки зрения, у него все еще есть проблема, и эта проблема потенциально может заставить что-то еще полностью не работать в какой-то момент. Если у вас никогда не было ошибки, вы, вероятно, потратите много времени на отладку.
его штраф, чтобы изменить уровень журнала или отключить отображение ошибок, но вы никогда не хотите, чтобы полностью подавить их.
Если вы хотите только surpress ошибку, вы можете сделать это:
Как правило, в php @ будет обрабатывать любую ошибку.
лучший способ-минимизировать вероятность ошибки. Вы сказали, что одна из возможностей ошибки вызвана несуществующим файлом. На твоем месте я бы сделал вот что:--3-->
этот метод может показаться странным, но я считаю, что это самый верный один
во-первых is_file это правильный метод, чтобы проверить, если файл не существует file_exists. file_exists проверяет как каталоги, так и файлы, поэтому может вернуть TRUE для каталога с тем же именем файла вы не можете удалить каталог с помощью unlink и это вызовет ошибку.
Проверка наличия файла (is_file) до unlink это правильный / лучший способ удалить файл.
но это не надежный метод, поскольку обычно файл удаляется в маленьком окне между is_file и unlink. Я испытал это несколько раз, когда метод кэширования использует файловую систему.
но это лучший способ.
так вы можете сделать все правильно и все равно получить ошибку!
ну, по крайней мере, ошибка говорит вам, если она терпит неудачу. ну на самом деле вы можете сказать, если это не удается без ошибок
возвращает TRUE или FALSE на провал.
если вы закодировали его правильно и можете различать успех и неудачу unlink затем да подавить ошибку, это не благослови тебя или твой код.
подавлена ли ошибка или нет, это лучший метод, который я могу придумать, чтобы предотвратить это. Сократив время между проверкой и удалением, вы уменьшите вероятность того, что он выдаст ошибку.
EDIT: обновленные URL-адреса ссылок
можно использовать is_writable чтобы проверить, есть ли у вас права на изменение или удаление файла.
Удаляет файл filename . Функция похожа на функцию unlink() Unix в C. При неудачном выполнении будет вызвана ошибка уровня E_WARNING .
Список параметров
Если файл является символической ссылкой, символическая ссылка будет удалена. В Windows для удаления символической ссылки на каталог вместо этого должна использоваться функция rmdir() .
Возвращаемые значения
Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.
Список изменений
Версия | Описание |
---|---|
7.3.0 | В Windows теперь можно удалить файлы функцией unlink() с использованием дескрипторов, хотя раньше это не удавалось. Тем не менее, всё ещё невозможно повторно создать удалённый файл, пока все дескрипторы к нему не будут закрыты. |
Примеры
Смотрите также
User Contributed Notes 11 notes
This will delete all files in a directory matching a pattern in one line of code.
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.
unlink($fileName); failed for me .
Then i tried using the realpath($fileName) function as
unlink(realpath($fileName)); it worked
just posting it , in case if any one finds it useful .
Here the simplest way to delete files with mask
$mask = "*.jpg"
array_map ( "unlink" , glob ( $mask ) );
?>
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:
// First close the file
fclose ( $fp );
// Then unlink :)
unlink ( $somefile );
?>
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 .
foreach ( glob ( "*.jpg" ) as $filename ) echo " $filename size " . filesize ( $filename ) . "\n" ;
unlink ( $filename );
>
This might seem obvious, but I was tearing my hair out with this problem - make sure the file you're trying to delete isn't currently being used. I had a script that was parsing a text file and was supposed to delete it after completing, but kept getting a permission denied error because I hadn't explicitly closed the file, hence it was technically still being "used" even though the parsing was complete.
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.
$old = getcwd (); // Save the current directory
chdir ( $path_to_file );
unlink ( $filename );
chdir ( $old ); // Restore the old working directory
?>
On OSX, when fighting against a "Permission Denied" error, make sure, the directory has WRITE permissions for the executing php-user.
Furthermore, if you rely on ACLs, and want to delete a file or symlink, the containing directory needs to have "delete_child" permission in order to unlink things inside. If you only grant "delete" to the folder that will allow you to delete the container folder itself, but not the objects inside.
unlink works the same as the rm command on nix based loses or del command on windows, it will not resolve the file but remove the exact path given even if that path is just a link.
E.G
/var/www/test/index.php = symlink(/home/test/www/index.php)
unlink ( "/var/www/test/index.php" );
?>
Will just delete the link, not the original file where as
unlink ( "/home/test/www/index.php" );
?>
Will unlink the original file path and break the symlink, and allow the system to overwrite as the filesystem will not know of the file's location anymore.
The best way to delete files by mask is as follows:
array_walk ( glob ( '/etc/*' ), 'unlink' );
?>
Do not use array_map mentioned below - it's purpose is to process values in a given array AND COLLECT data returned by the callback function. So, array_map is slower and uses additional memory compared to array_walk.
Deletes filename . Similar to the Unix C unlink() function. An E_WARNING level error will be generated on failure.
Parameters
Path to the file.
If the file is a symlink, the symlink will be deleted. On Windows, to delete a symlink to a directory, rmdir() has to be used instead.
Return Values
Returns true on success or false on failure.
Changelog
Version | Description |
---|---|
7.3.0 | On Windows, it is now possible to unlink() files with handles in use, while formerly that would fail. However, it is still not possible to re-create the unlinked file, until all handles to it have been closed. |
Examples
See Also
User Contributed Notes 11 notes
This will delete all files in a directory matching a pattern in one line of code.
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.
unlink($fileName); failed for me .
Then i tried using the realpath($fileName) function as
unlink(realpath($fileName)); it worked
just posting it , in case if any one finds it useful .
Here the simplest way to delete files with mask
$mask = "*.jpg"
array_map ( "unlink" , glob ( $mask ) );
?>
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:
// First close the file
fclose ( $fp );
// Then unlink :)
unlink ( $somefile );
?>
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 .
foreach ( glob ( "*.jpg" ) as $filename ) echo " $filename size " . filesize ( $filename ) . "\n" ;
unlink ( $filename );
>
This might seem obvious, but I was tearing my hair out with this problem - make sure the file you're trying to delete isn't currently being used. I had a script that was parsing a text file and was supposed to delete it after completing, but kept getting a permission denied error because I hadn't explicitly closed the file, hence it was technically still being "used" even though the parsing was complete.
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.
$old = getcwd (); // Save the current directory
chdir ( $path_to_file );
unlink ( $filename );
chdir ( $old ); // Restore the old working directory
?>
On OSX, when fighting against a "Permission Denied" error, make sure, the directory has WRITE permissions for the executing php-user.
Furthermore, if you rely on ACLs, and want to delete a file or symlink, the containing directory needs to have "delete_child" permission in order to unlink things inside. If you only grant "delete" to the folder that will allow you to delete the container folder itself, but not the objects inside.
unlink works the same as the rm command on nix based loses or del command on windows, it will not resolve the file but remove the exact path given even if that path is just a link.
E.G
/var/www/test/index.php = symlink(/home/test/www/index.php)
unlink ( "/var/www/test/index.php" );
?>
Will just delete the link, not the original file where as
unlink ( "/home/test/www/index.php" );
?>
Will unlink the original file path and break the symlink, and allow the system to overwrite as the filesystem will not know of the file's location anymore.
The best way to delete files by mask is as follows:
array_walk ( glob ( '/etc/*' ), 'unlink' );
?>
Do not use array_map mentioned below - it's purpose is to process values in a given array AND COLLECT data returned by the callback function. So, array_map is slower and uses additional memory compared to array_walk.
Пытается удалить директорию с именем directory . Директория должна быть пустой и должны иметься необходимые для этого права. При неудачном выполнении будет сгенерирована ошибка уровня E_WARNING .
Список параметров
Путь к директории.
Возвращаемые значения
Возвращает true в случае успешного выполнения или false в случае возникновения ошибки.
Примеры
Смотрите также
- is_dir() - Определяет, является ли имя файла директорией
- mkdir() - Создаёт директорию
- unlink() - Удаляет файл
User Contributed Notes 29 notes
Glob function doesn't return the hidden files, therefore scandir can be more useful, when trying to delete recursively a tree.
public static function delTree ( $dir ) <
$files = array_diff ( scandir ( $dir ), array( '.' , '..' ));
foreach ( $files as $file ) <
( is_dir ( " $dir / $file " )) ? delTree ( " $dir / $file " ) : unlink ( " $dir / $file " );
>
return rmdir ( $dir );
>
?>
The function delTree is dangerous when you dont take really care. I for example always deleted a temporary directory with it. Everthing went fine until the moment where the var containing this temporary directory wasnt set. The var didnt contain the path but an empty string. The function delTree was called and deleted all the files at my host!
So dont use this function when you dont have a proper handling coded. Dont think about using this function only for testing without such a handling.
Luckily nothing is lost because I had the local copy.
Never ever use jurchiks101 at gmail dot com code. It contains command injection vulnerability.
If you want to do it that way, use something like this instead:
if ( PHP_OS === 'Windows' )
exec ( sprintf ( "rd /s /q %s" , escapeshellarg ( $path )));
>
else
exec ( sprintf ( "rm -rf %s" , escapeshellarg ( $path )));
>
?>
Note the escapeshellarg usage to escape any possible unwanted character, this avoids putting commands in $path variable so the possibility of someone "pwning" the server with this code
some implementations of recursive folder delete don't work so well (some give warnings, other don't delete hidden files etc).
this one is working fine:
function rrmdir ( $src ) $dir = opendir ( $src );
while( false !== ( $file = readdir ( $dir )) ) if (( $file != '.' ) && ( $file != '..' )) $full = $src . '/' . $file ;
if ( is_dir ( $full ) ) rrmdir ( $full );
>
else unlink ( $full );
>
>
>
closedir ( $dir );
rmdir ( $src );
>
I was working on some Dataoperation, and just wanted to share an OOP method with you.
It just removes any contents of a Directory but not the target Directory itself! Its really nice if you want to clean a BackupDirectory or Log.
Also you can test on it if something went wrong or if it just done its Work!
I have it in a FileHandler class for example, enjoy!
public function deleteContent ( $path ) try $iterator = new DirectoryIterator ( $path );
foreach ( $iterator as $fileinfo ) if( $fileinfo -> isDot ())continue;
if( $fileinfo -> isDir ()) if( deleteContent ( $fileinfo -> getPathname ()))
@ rmdir ( $fileinfo -> getPathname ());
>
if( $fileinfo -> isFile ()) @ unlink ( $fileinfo -> getPathname ());
>
>
> catch ( Exception $e ) // write log
return false ;
>
return true ;
>
Say, you're working on Windows and continue to get a permission's error without a reason. Then it may be that a different Windows program is working on the folder (see earlier notes also). In the case that you can't find that program, the line
may solve the problem!
Make sure to write this before rmdir($dirname);.
Another simple way to recursively delete a directory that is not empty:
itay at itgoldman's function falls into an infinite loop if the $src directory doesn't exist.
Here's a fix - one should do at least a file_exists() check before the loop:
Thanks to itay for the original function, though, it was helpful.
// Recursive PHP function to completely remove a directory
function delete_directory_recursively( $path )
$dir = new \DirectoryIterator( $path );
// Iterate through the subdirectories / files of the provided directory
foreach ( $dir as $dir_info )
// Exclude the . (current directory) and .. (parent directory) paths
// from the directory iteration
if ( ! $dir_info->isDot() )
// Get the full currently iterated path
$iterated_path = $dir_info->getPathname();
// If the currently iterated path is a directory
if ( $dir_info->isDir() )
// which is not empty (in which case scandir returns an array of not 2 (. and ..) elements)
if ( count( scandir( $iterated_path ) ) !== 2 )
// Call the function recursively
self::remove_directory_recursively( $iterated_path );
// if the currently iterated path is an empty directory, remove it
rmdir( $iterated_path );
// If the currently iterated path describes a file, we need to
// delete that file
unlink( $iterated_path );
> // loop which opens if the currently iterated directory is neither . nor ..
> // end of iteration through directories / files of provided path
// After iterating through the subpaths of the provided path, remove the
// concerned path
rmdir( $path );
> // end of delete_directory_recursively() function definition
I also ran into the permissions issue in Windows when deleting a folder and the solution was to close all editors which had files opened which were located in the folder structure.
This issue has been driving me nuts for hours.
I am running PHP on IIS, I had the wincache module installed, when running a recursive delete a certain folder would get "stuck" and throw permissions errors. I was not able to delete them with PHP or in windows itself. The only way to delete the folder was to wait 5 min and run the script again, or stop the IIS server and the folder would delete on its own. Disabling the wincachce module resolved the issue.
Hope this helps.
function unlinkDir($dir)
$dirs = array($dir);
$files = array() ;
for($i=0;;$i++)
if(isset($dirs[$i]))
$dir = $dirs[$i];
else
break ;
if($openDir = opendir($dir))
while($readDir = @readdir($openDir))
if($readDir != "." && $readDir != "..")
foreach($files as $file)
unlink($file) ;
>
$dirs = array_reverse($dirs) ;
foreach($dirs as $dir)
rmdir($dir) ;
>
It is rather dangerous to recurse into symbolically linked directories. The delTree should be modified to check for links.
public static function delTree ( $dir ) <
$files = array_diff ( scandir ( $dir ), array( '.' , '..' ));
foreach ( $files as $file ) <
( is_dir ( " $dir / $file " ) && ! is_link ( $dir )) ? delTree ( " $dir / $file " ) : unlink ( " $dir / $file " );
>
return rmdir ( $dir );
>
?>
it Will Delete All Fildes in folder and that folder too.
echo $path = 'D:\xampp\htdocs\New folder\New folder';
function rmdir_recursive($dir) $it = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
$it = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
foreach($it as $file) if ($file->isDir()) rmdir($file->getPathname());
else unlink($file->getPathname());
>
rmdir($dir);
>
rmdir_recursive($path);
I've noticed that when using this command on a windows platform you may encounter a permissions error which may seem unwarranted. This commonly occurs if you are or were using a program to edit something in the to be deleted folder and either the item is still in the folder or the program that was accessing the file in that folder is still running(causing it to hold onto the folder).
SO. if you get a permissions error and there shouldn't be an issue with folder permissions check if there are files in there then check if there is a program running that is or was using a file that was in that folder and kill it.
Keep in mind that if you know what your host OS is, you can always just call the appropriate system call using exec() or the like. For example:
exec('rmdir folder-to-delete /s /q'); //windows
exec('rmdir -rf folder-to-delete'); //OS X/*nix?
while ($contents = readdir($directoryHandle))
if a folder named 0 (zero) is found during traversing the hierarchy
Works fine, tested on PHP 5.4(EasyPHP server)
function deletedir($dir)
if (is_dir($dir))
<
$files = scandir($dir);
foreach ($files as $file)
<
if ($file != "." && $file != "..")
<
if (filetype($dir."/".$file) == "dir")
$this->deletedir($dir."/".$file);
>
else
unlink($dir."/".$file);
>
>
>
reset($objects);
if(rmdir($dir))
return 'deleted successfully!';
>
else
return 'delete failed!';
>
>
else
return 'doesn\'t exist or inaccessible!';
>
>
Something to note:
You have to take care of file permission if necessary
A patch to previous script to make sure rights for deletion is set:
//Delete folder function
function deleteDirectory ( $dir ) <
if (! file_exists ( $dir )) return true ;
if (! is_dir ( $dir ) || is_link ( $dir )) return unlink ( $dir );
foreach ( scandir ( $dir ) as $item ) <
if ( $item == '.' || $item == '..' ) continue;
if (! deleteDirectory ( $dir . "/" . $item )) <
chmod ( $dir . "/" . $item , 0777 );
if (! deleteDirectory ( $dir . "/" . $item )) return false ;
>;
>
return rmdir ( $dir );
>
?>
[EDITOR NOTE: "Credits to erkethan at free dot fr." - thiago]
Sometimes you would face situations in which rmdir($dirname) would give "permission denied" errors though you may have changed $dirname permissions. In such situations just change the permissions of the directory which contains $dirname and rmdir($dirname) would work like a charm.
Say you use rmdir('dirr'); then change the permissions of the folder that contains 'dirr'.
if you get this problem Permission denied in windows testing your site maybe this will resolve the problem
if( file_exists ( $path . '/Thumbs.db' )) <
unlink ( $path . '/Thumbs.db' );
>
?>
and then
In case you're trying to rmdir() and you keep getting 'Permission denied' errors, make sure you don't have the directory still open after using opendir(). Especially when writing recursive functions for deleting directories, make sure you have closedir() BEFORE rmdir().
I wasn't having much luck with the recursive delete functions below, so I wrote my own:
// ensure $dir ends with a slash
function delTree ( $dir ) <
$files = glob ( $dir . '*' , GLOB_MARK );
foreach( $files as $file ) <
if( substr ( $file , - 1 ) == '/' )
delTree ( $file );
else
unlink ( $file );
>
rmdir ( $dir );
>
?>
Simple. Works.
Concise way to recursively remove a directory:
This isn't my code, but just thought I would share, since it took me so long to find. This is a function to delete a folder, all sub-folders, and files in one clean move.
Just tell it what directory you want deleted, in relation to the page that this function is executed. Then set $empty = true if you want the folder just emptied, but not deleted. If you set $empty = false, or just simply leave it out, the given directory will be deleted, as well.
function deleteAll ( $directory , $empty = false ) <
if( substr ( $directory ,- 1 ) == "/" ) <
$directory = substr ( $directory , 0 ,- 1 );
>
if(! file_exists ( $directory ) || ! is_dir ( $directory )) <
return false ;
> elseif(! is_readable ( $directory )) <
return false ;
> else <
$directoryHandle = opendir ( $directory );
if( is_dir ( $path )) <
deleteAll ( $path );
> else <
unlink ( $path );
>
>
>
if( $empty == false ) <
if(! rmdir ( $directory )) <
return false ;
>
>
I had situation where the rmdir was returning warning message as within last loop it was already removed. So here is quick fix by adding is_dir to the DelTree routine below
function delTree ( $dir ) <
$files = glob ( $dir . '*' , GLOB_MARK );
foreach( $files as $file ) <
if( substr ( $file , - 1 ) == '/' )
delTree ( $file );
else
unlink ( $file );
>
Сделал скрипт и туда занес удаление файла по абсолютному пути сервера
Запускаю скрипт с браузера, файл удаляется нормально.
Далее у меня есть програмка на delphi которая периодически запускает другой скрипт на сервере. ( скрипт от программы принимает довольно много данных так что отдельно от программы я с эмитировать его работу и посмотреть есть ли ошибки не могу) К тому же, если выложу весь скрипт, могут найтись люди , которые воспользуются багами, чтобы сломать мне работу(
В этот скрипт я занес точно такую же команду удаления файла и не удаляется файл. Скрипты находятся в одной папке, хотя это и неважно, так как путь абсолютный.
Сама работа скрипта остается правильной, вот за исключением того что файл не удаляется.
Я понимаю что не выкладываю никакого кода, но он только запутает вас.
В чем могут быть проблемы?
Мне нужно чтобы это делал скрипт php, который вызывается программой. Это не одноразовая операция, она будет происходить довольно часто. Т.е. Этот файл будет создаваться, модифицироваться, а потом удаляться.
Нужно посмотреть логи web-сервера на предмет ошибок при попытках удаления файла.
Если файл по какой-либо причине не удаляется при вызове unlink – в логах должна быть ошибка, описывающая суть проблемы.
Возможно, проблемы с правами доступа.
Нужно посмотреть логи web-сервера на предмет ошибок при попытках удаления файла.
Если файл по какой-либо причине не удаляется при вызове unlink – в логах должна быть ошибка, описывающая суть проблемы.
Возможно, проблемы с правами доступа.
А не подскажите в каких это логах искать?
Просматриваю:
syslog
system.log
dovecot.log
nginx-error.log
php-fpm.log
и другие не могу найти покачто где эти ошибки отображаются(
Смотреть нужно error.log, относящийся к виртуальному хосту, в котором работает скрипт.
Хотя, в случае вызова скрипта через delphi я не уверен, что это именно так – возможно, запись идет в некий общий файл ошибок
(в php.ini должен быть указан путь к этому файлу: типа «error_log = /var/log/php-scripts.log», или можно в консоли поиск выполнить: «php --info | grep error»).
Можно попробовать заюзать error_log для фиксации конкретной ошибки в указанный файл.
А какие права установлены на каталог, в котором находится сам удаляемый файл?
Читайте также: