PHP Conference Japan 2024

rmdir

(PHP 4, PHP 5, PHP 7, PHP 8)

rmdir移除目錄

描述

rmdir(字串 $directory, ?資源 $context = null): 布林值

嘗試移除由 directory 指定的目錄。該目錄必須為空,且相關的權限必須允許此操作。若失敗將會產生 E_WARNING 等級的錯誤。

參數

directory

目錄的路徑。

context

上下文串流 資源

回傳值

成功時回傳 true,失敗時回傳 false

範例

範例 1 rmdir() 範例

<?php
if (!is_dir('examples')) {
mkdir('examples');
}

rmdir('examples');
?>

參見

新增註解

使用者貢獻的註解 25 個註解

208
nbari at dalmp dot com
12 年前
Glob 函數不會回傳隱藏檔案,因此當嘗試遞迴刪除樹狀結構時,scandir 會更有用。

<?php
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);
}
?>
36
itay at itgoldman dot com
9 年前
一些遞迴刪除資料夾的實作效果不佳(有些會給予警告,有些則不會刪除隱藏檔案等)。

這個可以正常運作
<?php

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);
}

?>
47
info at top-info dot org
14 年前
當您沒有真正小心時,delTree 函數會很危險。例如,我總是使用它來刪除暫存目錄。一切順利,直到包含此暫存目錄的變數未設定的那一刻。該變數沒有包含路徑,而是包含一個空字串。delTree 函數被呼叫並刪除了我主機上的所有檔案!
因此,當您沒有編寫適當的處理程序時,請勿使用此函數。不要只想在沒有這種處理程序的情況下使用此函數進行測試。
幸運的是,沒有任何損失,因為我擁有本地副本...
36
dj dot thd at hotmail dot com
8 年前
永遠不要使用 jurchiks101 at gmail dot com 的程式碼!!!它包含命令注入漏洞!!!
如果您想以這種方式執行,請改用類似以下的方法

<?php
if (PHP_OS === 'Windows')
{
exec(sprintf("rd /s /q %s", escapeshellarg($path)));
}
else
{
exec(sprintf("rm -rf %s", escapeshellarg($path)));
}
?>

請注意使用 escapeshellarg 來跳脫任何可能不需要的字元,這避免了將命令放入 $path 變數中,從而避免有人使用此程式碼「pwning」伺服器的可能性
46
holger1 at NOSPAMzentralplan dot de
14 年前
另一種簡單的方法來遞迴刪除非空目錄

<?php
function rrmdir($dir) {
if (
is_dir($dir)) {
$objects = scandir($dir);
foreach (
$objects as $object) {
if (
$object != "." && $object != "..") {
if (
filetype($dir."/".$object) == "dir") rrmdir($dir."/".$object); else unlink($dir."/".$object);
}
}
reset($objects);
rmdir($dir);
}
}
?>
14
wolfoneil at gmx.de
9 年前
我正在處理一些資料操作,只是想和大家分享一個物件導向的方法。

它只會移除目錄中的所有內容,但不會移除目標目錄本身!如果你想清理備份目錄或日誌,這非常方便。

你也可以用它來測試是否有任何錯誤發生,或是它是否已完成工作!

我把它放在一個 FileHandler 類別中,例如,請享用!

<?php

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;
}

?>
6
steffen at wirsching-idstein dot de
14 年前
假設你在 Windows 上工作,卻一直遇到權限錯誤,而且沒有原因。那麼可能是另一個 Windows 程式正在使用該資料夾(也請參閱先前的註解)。如果你找不到該程式,那麼這行

<?php closedir(opendir($dirname)); ?>

或許可以解決問題!
請務必在 rmdir($dirname); 之前寫下這行。
8
Anonymous
8 年前
如果 $src 目錄不存在,itay at itgoldman 的函式會進入無限迴圈。
這是一個修正方法 - 至少應該在迴圈之前檢查 file_exists()

function rrmdir($src) {
if (file_exists($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);
}
}

感謝 itay 的原始函式,它很有幫助。
6
shane dot ray87 at gmail dot com
13 年前
這個問題困擾我好幾個小時了。

我正在 IIS 上執行 PHP,我安裝了 wincache 模組,當執行遞迴刪除時,某個資料夾會「卡住」並拋出權限錯誤。我無法使用 PHP 或 Windows 本身刪除它們。刪除資料夾的唯一方法是等待 5 分鐘然後再次執行腳本,或停止 IIS 伺服器,資料夾就會自行刪除。停用 wincachce 模組解決了此問題。

希望這有幫助。
5
Chris Wren
12 年前
我也在 Windows 中刪除資料夾時遇到權限問題,解決方案是關閉所有開啟了位於該資料夾結構中的檔案的編輯器。
5
thomas
13 年前
O S 在 2010 年 6 月 18 日 11:30 提供的函式 deleteAll 會在這一行失敗

while ($contents = readdir($directoryHandle)) {...

如果在遍歷層次結構時發現名為 0(零)的資料夾
5
tuxedobob
10 年前
請記住,如果你知道你的主機作業系統是什麼,你總是可以使用 exec() 之類的指令來呼叫適當的系統呼叫。例如

exec('rmdir folder-to-delete /s /q'); //windows
exec('rmdir -rf folder-to-delete'); //OS X/*nix?
12
lprent at primary dot geek dot nz
10 年前
遞迴進入符號連結的目錄是相當危險的。delTree 應該修改為檢查連結。

<?php
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);
}
?>
4
ahmadmarafa at gmail dot com
10 年前
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 != "..")
{

if(is_dir($dir."/".$readDir))
{
$dirs[] = $dir."/".$readDir ;
}
else
{

$files[] = $dir."/".$readDir ;
}
}
}

}

}



foreach($files as $file)
{
unlink($file) ;

}
$dirs = array_reverse($dirs) ;
foreach($dirs as $dir)
{
rmdir($dir) ;
}

}
2
mmakshita2398 at gmail dot com
5 年前
它會刪除資料夾中的所有檔案,以及該資料夾本身...

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);
3
rn at clubfl dot com
16 年前
我注意到,當在 Windows 平台上使用此命令時,您可能會遇到權限錯誤,這似乎是不合理的。如果您正在或曾經使用程式來編輯要刪除的資料夾中的某些內容,並且該項目仍在資料夾中,或者存取該資料夾中檔案的程式仍在執行(導致它持有該資料夾),通常會發生這種情況。

所以...如果您遇到權限錯誤,並且資料夾權限不應該有問題,請檢查其中是否有檔案,然後檢查是否有程式正在執行,該程式正在或曾經使用該資料夾中的檔案,並將其終止。
5
asn at asn24 dot dk
15 年前
對先前腳本的修補程式,以確保設定刪除權限

<?php
//刪除資料夾函數
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);
}
?>

[編輯者註:「感謝 free dot fr 的 erkethan。」- thiago]
4
omikrosys at gmail dot com
15 年前
有時你會遇到即使你已更改 `$dirname` 的權限,`rmdir($dirname)` 仍會出現「權限不足」錯誤的情況。在這種情況下,只需更改包含 `$dirname` 的目錄的權限,`rmdir($dirname)` 就會正常運作。
例如,你使用 `rmdir('dirr');`,然後更改包含 'dirr' 的資料夾的權限。
2
Baraka Mghumba
10 年前
運作良好,已在 PHP 5.4(EasyPHP 伺服器)上測試。
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!';
}
}
注意事項
如有必要,你必須注意檔案權限
1
O S
14 年前
這不是我的程式碼,但我想分享一下,因為我花了很長時間才找到。這是一個可以一次性清除資料夾、所有子資料夾和檔案的函式。

只需告訴它你想要刪除的目錄,相對於執行此函式的頁面而言。然後,如果你只想清空資料夾但不刪除它,請設定 `$empty = true`。如果你設定 `$empty = false`,或直接省略不寫,則指定的目錄也會被刪除。

<?php
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);

while (
$contents = readdir($directoryHandle)) {
if(
$contents != '.' && $contents != '..') {
$path = $directory . "/" . $contents;

if(
is_dir($path)) {
deleteAll($path);
} else {
unlink($path);
}
}
}

closedir($directoryHandle);

if(
$empty == false) {
if(!
rmdir($directory)) {
return
false;
}
}

return
true;
}
}
?>
1
samy dot see at gmail dot com
13 年前
如果你在 Windows 上測試網站時遇到「權限不足」的問題,也許這可以解決問題

<?php
if(file_exists($path.'/Thumbs.db')){
unlink($path.'/Thumbs.db');
}
?>

然後

<?php rmdir($path); ?>
0
dev dot abi dot log at gmail dot com
2 年前
一個用於遞迴移除空目錄的簡單片段

<?php
function removeEmptyDirs($fullPath)
{
if(!
is_dir($fullPath)){
return;
}

$children = array_diff(scandir($fullPath), ['.','..']);

foreach(
$children as $child){
removeEmptyDirs($fullPath. $child. DIRECTORY_SEPARATOR);
}

$children = array_diff(scandir($fullPath), ['.','..']);
if(empty(
$children)){
echo
"the $fullPath empty directory has been removed.\n";
rmdir($fullPath);
}
}
?>
0
anonymous_user
3 年前
// 用於完全移除目錄的遞迴 PHP 函式

function delete_directory_recursively( $path ) {

$dir = new \DirectoryIterator( $path );

// 迭代提供的目錄的子目錄/檔案
foreach ( $dir as $dir_info ) {

// 從目錄迭代中排除 .(目前目錄)和 ..(父目錄)路徑
// 從目錄迭代中排除 .(目前目錄)和 ..(父目錄)路徑
if ( ! $dir_info->isDot() ) {

// 取得目前迭代的路徑
$iterated_path = $dir_info->getPathname();

// 如果目前迭代的路徑是一個目錄
if ( $dir_info->isDir() ) {

// 且不是空的(在這種情況下,scandir 會傳回一個不是 2 個(. 和 ..)元素的陣列)
if ( count( scandir( $iterated_path ) ) !== 2 ) {

// 遞迴呼叫函式
self::remove_directory_recursively( $iterated_path );

} else {

// 如果目前迭代的路徑是一個空的目錄,請將其移除
rmdir( $iterated_path );

}

} elseif ( $dir_info->isFile() ) {

// 如果目前迭代的路徑描述一個檔案,我們需要
// 刪除該檔案
unlink( $iterated_path );

}

} // 開啟迴圈,如果目前迭代的目錄既不是 . 也不是 ..

} // 結束迭代提供的路徑的目錄/檔案

// 在迭代提供的路徑的子路徑之後,移除
// 相關的路徑
rmdir( $path );

} // 結束 delete_directory_recursively() 函式定義
1
TrashF at taistelumarsu dot org
16 年前
如果你嘗試使用 `rmdir()` 並持續收到「權限不足」錯誤,請確保在使用 `opendir()` 後沒有仍然開啟該目錄。尤其是在編寫用於刪除目錄的遞迴函式時,請確保在 `rmdir()` 之前已執行 `closedir()`。
1
longears at BLERG dot gmail dot com
12 年前
遞迴移除目錄的簡潔方法

<?php
# 遞迴移除目錄
function rrmdir($dir) {
foreach(
glob($dir . '/*') as $file) {
if(
is_dir($file))
rrmdir($file);
else
unlink($file);
}
rmdir($dir);
}
?>
To Top