rmdir() 函数用于删除空目录。如果目录不为空,则删除失败。要删除非空目录,需要先递归删除目录中的所有文件和子目录。
rmdir() 函数是文件系统操作中的基础函数,常用于清理临时目录、删除上传目录、或管理缓存目录等场景。
rmdir(string $directory, ?resource $context = null): bool
| 参数 | 描述 |
|---|---|
| directory |
必需。要删除的目录的路径。 必须是空目录,否则删除失败。可以是绝对路径或相对路径。 |
| context |
可选。流上下文(stream context)资源。 用于指定流的特殊选项,例如删除 FTP 目录时需要。 |
| 返回值 | 描述 |
|---|---|
| TRUE | 目录删除成功 |
| FALSE | 目录删除失败(目录不为空、权限不足、目录不存在等) |
<?php
// 创建测试目录
$dir = "/tmp/test_rmdir";
if (!is_dir($dir)) {
mkdir($dir, 0755);
echo "目录创建成功: $dir<br>";
}
// 删除空目录
if (rmdir($dir)) {
echo "目录删除成功: $dir<br>";
} else {
echo "目录删除失败: $dir<br>";
}
// 尝试删除非空目录
$dir2 = "/tmp/test_rmdir2";
if (!is_dir($dir2)) {
mkdir($dir2, 0755);
file_put_contents($dir2 . "/test.txt", "测试文件");
echo "创建非空目录: $dir2<br>";
}
if (rmdir($dir2)) {
echo "目录删除成功: $dir2<br>";
} else {
echo "目录删除失败 (因为目录非空): $dir2<br>";
// 清理
unlink($dir2 . "/test.txt");
rmdir($dir2);
}
?>
<?php
/**
* 递归删除目录及其所有内容
* @param string $dir 要删除的目录路径
* @return bool 是否成功
*/
function deleteDirectory($dir) {
// 检查目录是否存在
if (!is_dir($dir)) {
return false;
}
// 打开目录
$items = scandir($dir);
if ($items === false) {
return false;
}
// 遍历目录内容
foreach ($items as $item) {
if ($item === '.' || $item === '..') {
continue;
}
$path = $dir . DIRECTORY_SEPARATOR . $item;
if (is_dir($path)) {
// 递归删除子目录
if (!deleteDirectory($path)) {
return false;
}
} else {
// 删除文件
if (!unlink($path)) {
return false;
}
}
}
// 删除空目录
return rmdir($dir);
}
// 使用示例
$testDir = "/tmp/recursive_delete_test";
if (!is_dir($testDir)) {
mkdir($testDir, 0755, true);
// 创建测试文件和子目录
file_put_contents($testDir . "/file1.txt", "文件1");
file_put_contents($testDir . "/file2.txt", "文件2");
mkdir($testDir . "/subdir1", 0755);
file_put_contents($testDir . "/subdir1/file3.txt", "文件3");
mkdir($testDir . "/subdir2", 0755);
mkdir($testDir . "/subdir2/deepdir", 0755);
file_put_contents($testDir . "/subdir2/deepdir/file4.txt", "文件4");
echo "测试目录结构创建完成: $testDir<br>";
// 递归删除
if (deleteDirectory($testDir)) {
echo "目录递归删除成功: $testDir<br>";
} else {
echo "目录递归删除失败: $testDir<br>";
}
} else {
echo "测试目录已存在,跳过创建<br>";
}
?>
<?php
/**
* 安全删除目录,带有验证和可选的备份
*/
class SafeDirectoryRemover {
/**
* 安全删除目录
* @param string $dir 要删除的目录
* @param bool $backup 是否先备份
* @param string $backupDir 备份目录
* @return array 操作结果
*/
public static function safeRemove($dir, $backup = false, $backupDir = null) {
$result = [
'success' => false,
'message' => '',
'backup_path' => null
];
// 验证目录
if (!is_dir($dir)) {
$result['message'] = "目录不存在: $dir";
return $result;
}
// 检查目录是否可写
if (!is_writable($dir)) {
$result['message'] = "目录不可写: $dir";
return $result;
}
// 备份目录(如果需要)
if ($backup) {
$backupPath = self::backupDirectory($dir, $backupDir);
if ($backupPath) {
$result['backup_path'] = $backupPath;
} else {
$result['message'] = "目录备份失败: $dir";
return $result;
}
}
// 递归删除目录
if (self::recursiveRemove($dir)) {
$result['success'] = true;
$result['message'] = "目录删除成功: $dir";
} else {
$result['message'] = "目录删除失败: $dir";
}
return $result;
}
/**
* 备份目录
*/
private static function backupDirectory($sourceDir, $backupDir = null) {
if ($backupDir === null) {
$backupDir = dirname($sourceDir) . '/backups';
}
// 创建备份目录
if (!is_dir($backupDir)) {
mkdir($backupDir, 0755, true);
}
$timestamp = date('Y-m-d_H-i-s');
$backupName = basename($sourceDir) . '_' . $timestamp;
$backupPath = $backupDir . '/' . $backupName;
// 复制目录
if (self::copyDirectory($sourceDir, $backupPath)) {
return $backupPath;
}
return false;
}
/**
* 复制目录
*/
private static function copyDirectory($source, $dest) {
if (!is_dir($source)) {
return false;
}
if (!is_dir($dest)) {
mkdir($dest, 0755, true);
}
$items = scandir($source);
if ($items === false) {
return false;
}
foreach ($items as $item) {
if ($item === '.' || $item === '..') {
continue;
}
$srcPath = $source . '/' . $item;
$dstPath = $dest . '/' . $item;
if (is_dir($srcPath)) {
if (!self::copyDirectory($srcPath, $dstPath)) {
return false;
}
} else {
if (!copy($srcPath, $dstPath)) {
return false;
}
}
}
return true;
}
/**
* 递归删除目录
*/
private static function recursiveRemove($dir) {
if (!is_dir($dir)) {
return false;
}
$items = scandir($dir);
if ($items === false) {
return false;
}
foreach ($items as $item) {
if ($item === '.' || $item === '..') {
continue;
}
$path = $dir . '/' . $item;
if (is_dir($path)) {
if (!self::recursiveRemove($path)) {
return false;
}
} else {
if (!unlink($path)) {
return false;
}
}
}
return rmdir($dir);
}
/**
* 删除旧备份
* @param string $backupDir 备份目录
* @param int $maxAgeDays 最大保留天数
* @return array 删除结果
*/
public static function cleanupOldBackups($backupDir, $maxAgeDays = 30) {
$results = [
'total' => 0,
'deleted' => 0,
'errors' => []
];
if (!is_dir($backupDir)) {
return $results;
}
$items = scandir($backupDir);
$cutoffTime = time() - ($maxAgeDays * 24 * 60 * 60);
foreach ($items as $item) {
if ($item === '.' || $item === '..') {
continue;
}
$path = $backupDir . '/' . $item;
$results['total']++;
// 检查文件/目录时间
$fileTime = filemtime($path);
if ($fileTime < $cutoffTime) {
if (is_dir($path)) {
if (self::recursiveRemove($path)) {
$results['deleted']++;
} else {
$results['errors'][] = "无法删除旧备份: $path";
}
} else {
if (unlink($path)) {
$results['deleted']++;
} else {
$results['errors'][] = "无法删除旧备份文件: $path";
}
}
}
}
return $results;
}
}
// 使用示例
echo "<h4>安全目录删除示例</h4>";
// 创建测试目录
$testDir = "/tmp/safe_delete_test";
if (!is_dir($testDir)) {
mkdir($testDir, 0755, true);
// 创建一些测试文件
file_put_contents($testDir . "/important.txt", "重要文件");
mkdir($testDir . "/data", 0755);
file_put_contents($testDir . "/data/log.txt", "日志内容");
echo "测试目录创建完成: $testDir<br>";
}
// 安全删除(带备份)
echo "<br>执行安全删除(带备份):<br>";
$result = SafeDirectoryRemover::safeRemove($testDir, true, '/tmp/backups');
if ($result['success']) {
echo "删除成功: " . $result['message'] . "<br>";
if ($result['backup_path']) {
echo "备份路径: " . $result['backup_path'] . "<br>";
}
} else {
echo "删除失败: " . $result['message'] . "<br>";
}
// 清理旧备份示例
echo "<br>清理旧备份示例:<br>";
$cleanupResult = SafeDirectoryRemover::cleanupOldBackups('/tmp/backups', 1); // 保留1天
echo "总共检查: " . $cleanupResult['total'] . " 个备份<br>";
echo "已删除: " . $cleanupResult['deleted'] . " 个旧备份<br>";
if (count($cleanupResult['errors']) > 0) {
echo "错误:<br>";
foreach ($cleanupResult['errors'] as $error) {
echo "- $error<br>";
}
}
?>
<?php
// 删除FTP目录的示例
function removeFtpDirectory($ftpServer, $username, $password, $remoteDir) {
// 创建FTP连接
$connId = ftp_connect($ftpServer);
if (!$connId) {
return "无法连接到FTP服务器: $ftpServer";
}
// 登录FTP
if (!ftp_login($connId, $username, $password)) {
ftp_close($connId);
return "FTP登录失败";
}
// 开启被动模式
ftp_pasv($connId, true);
// 递归删除FTP目录
function deleteFtpDirectory($connId, $directory) {
// 获取目录列表
$files = ftp_nlist($connId, $directory);
if ($files === false) {
return false;
}
foreach ($files as $file) {
// 跳过 . 和 ..
if ($file === '.' || $file === '..') {
continue;
}
$fullPath = $directory . '/' . basename($file);
// 检查是文件还是目录
if (ftp_size($connId, $fullPath) == -1) {
// 是目录,递归删除
if (!deleteFtpDirectory($connId, $fullPath)) {
return false;
}
} else {
// 是文件,删除文件
if (!ftp_delete($connId, $fullPath)) {
return false;
}
}
}
// 删除空目录
return ftp_rmdir($connId, $directory);
}
// 删除目录
if (deleteFtpDirectory($connId, $remoteDir)) {
ftp_close($connId);
return "FTP目录删除成功: $remoteDir";
} else {
$error = "无法删除FTP目录: $remoteDir";
ftp_close($connId);
return $error;
}
}
// 本地模拟FTP删除(实际使用需要FTP服务器)
echo "<h4>FTP目录删除示例</h4>";
echo "注:此示例需要真实的FTP服务器才能运行<br>";
echo "函数签名: removeFtpDirectory(\$ftpServer, \$username, \$password, \$remoteDir)<br><br>";
// 实际应用:清理临时目录
function cleanupTempDirectory($dir, $maxAgeHours = 24) {
if (!is_dir($dir)) {
return ['success' => false, 'message' => "目录不存在: $dir"];
}
$cutoffTime = time() - ($maxAgeHours * 60 * 60);
$stats = [
'directories_deleted' => 0,
'files_deleted' => 0,
'errors' => []
];
$items = scandir($dir);
foreach ($items as $item) {
if ($item === '.' || $item === '..') {
continue;
}
$path = $dir . '/' . $item;
$fileTime = filemtime($path);
// 检查是否超过最大时间
if ($fileTime < $cutoffTime) {
if (is_dir($path)) {
// 递归删除旧目录
if (deleteDirectory($path)) {
$stats['directories_deleted']++;
} else {
$stats['errors'][] = "无法删除目录: $path";
}
} else {
// 删除旧文件
if (unlink($path)) {
$stats['files_deleted']++;
} else {
$stats['errors'][] = "无法删除文件: $path";
}
}
}
}
return [
'success' => true,
'message' => "清理完成,删除 {$stats['directories_deleted']} 个目录和 {$stats['files_deleted']} 个文件",
'stats' => $stats
];
}
// 清理临时目录示例
echo "<h4>临时目录清理示例</h4>";
// 创建一些测试临时文件和目录
$tempDir = "/tmp/cleanup_test";
if (!is_dir($tempDir)) {
mkdir($tempDir, 0755);
}
// 创建一些文件(模拟不同时间的文件)
file_put_contents($tempDir . "/recent.txt", "新文件");
touch($tempDir . "/recent.txt", time() - 3600); // 1小时前
file_put_contents($tempDir . "/old.txt", "旧文件");
touch($tempDir . "/old.txt", time() - 48 * 3600); // 2天前
mkdir($tempDir . "/old_dir", 0755);
touch($tempDir . "/old_dir", time() - 72 * 3600); // 3天前
echo "临时目录内容创建完成: $tempDir<br>";
// 清理超过24小时的旧文件
$result = cleanupTempDirectory($tempDir, 24);
echo $result['message'] . "<br>";
if (count($result['stats']['errors']) > 0) {
echo "清理错误:<br>";
foreach ($result['stats']['errors'] as $error) {
echo "- $error<br>";
}
}
// 删除测试目录
if (is_dir($tempDir)) {
deleteDirectory($tempDir);
}
?>
<?php
/**
* 带有错误处理和重试机制的目录删除
*/
class RobustDirectoryRemover {
/**
* 安全删除目录,带有重试机制
*/
public static function robustRemove($dir, $maxRetries = 3, $delayMs = 100) {
// 验证目录是否存在
if (!is_dir($dir)) {
return [
'success' => false,
'message' => "目录不存在: $dir",
'retries' => 0
];
}
// 检查目录是否可写
if (!is_writable($dir)) {
return [
'success' => false,
'message' => "目录不可写: $dir",
'retries' => 0
];
}
// 尝试删除(带重试)
$attempt = 0;
while ($attempt < $maxRetries) {
$attempt++;
try {
// 清除状态缓存
clearstatcache();
// 递归删除目录
if (self::recursiveRemoveWithRetry($dir, $maxRetries, $delayMs)) {
return [
'success' => true,
'message' => "目录删除成功: $dir (尝试次数: $attempt)",
'retries' => $attempt
];
}
// 如果失败,等待后重试
if ($attempt < $maxRetries) {
usleep($delayMs * 1000);
}
} catch (Exception $e) {
error_log("删除目录时出错 (尝试 $attempt): " . $e->getMessage());
if ($attempt < $maxRetries) {
usleep($delayMs * 1000);
}
}
}
return [
'success' => false,
'message' => "无法删除目录: $dir (最大重试次数: $maxRetries)",
'retries' => $attempt
];
}
/**
* 递归删除目录(带重试)
*/
private static function recursiveRemoveWithRetry($dir, $maxRetries, $delayMs) {
if (!is_dir($dir)) {
return true;
}
$items = scandir($dir);
if ($items === false) {
return false;
}
foreach ($items as $item) {
if ($item === '.' || $item === '..') {
continue;
}
$path = $dir . '/' . $item;
if (is_dir($path)) {
// 递归删除子目录
if (!self::recursiveRemoveWithRetry($path, $maxRetries, $delayMs)) {
return false;
}
} else {
// 删除文件(带重试)
if (!self::retryUnlink($path, $maxRetries, $delayMs)) {
return false;
}
}
}
// 删除空目录(带重试)
return self::retryRmdir($dir, $maxRetries, $delayMs);
}
/**
* 重试删除文件
*/
private static function retryUnlink($file, $maxRetries, $delayMs) {
$attempt = 0;
while ($attempt < $maxRetries) {
$attempt++;
if (unlink($file)) {
return true;
}
if ($attempt < $maxRetries) {
usleep($delayMs * 1000);
clearstatcache();
}
}
return false;
}
/**
* 重试删除目录
*/
private static function retryRmdir($dir, $maxRetries, $delayMs) {
$attempt = 0;
while ($attempt < $maxRetries) {
$attempt++;
if (rmdir($dir)) {
return true;
}
if ($attempt < $maxRetries) {
usleep($delayMs * 1000);
clearstatcache();
}
}
return false;
}
/**
* 批量删除目录
*/
public static function batchRemove(array $dirs, $maxRetries = 3) {
$results = [];
foreach ($dirs as $index => $dir) {
$results[$index] = self::robustRemove($dir, $maxRetries);
}
return $results;
}
/**
* 删除目录,但保留某些文件/目录
*/
public static function removeWithExclusions($dir, $exclusions = []) {
if (!is_dir($dir)) {
return false;
}
$items = scandir($dir);
if ($items === false) {
return false;
}
foreach ($items as $item) {
if ($item === '.' || $item === '..') {
continue;
}
// 检查是否在排除列表中
if (in_array($item, $exclusions)) {
continue;
}
$path = $dir . '/' . $item;
if (is_dir($path)) {
if (!self::removeWithExclusions($path, $exclusions)) {
return false;
}
} else {
if (!unlink($path)) {
return false;
}
}
}
// 检查目录是否为空(排除排除项)
$remainingItems = array_diff(scandir($dir), ['.', '..']);
$remainingItems = array_diff($remainingItems, $exclusions);
if (empty($remainingItems)) {
return rmdir($dir);
}
return true;
}
}
// 使用示例
echo "<h4>健壮的目录删除示例</h4>";
// 创建测试目录结构
$testDir = "/tmp/robust_remove_test";
if (!is_dir($testDir)) {
mkdir($testDir, 0755, true);
// 创建一些文件和子目录
for ($i = 1; $i <= 5; $i++) {
file_put_contents($testDir . "/file{$i}.txt", "文件{$i}内容");
}
mkdir($testDir . "/subdir", 0755);
file_put_contents($testDir . "/subdir/deep.txt", "深层文件");
echo "测试目录创建完成: $testDir<br>";
}
// 健壮删除
echo "<br>执行健壮删除:<br>";
$result = RobustDirectoryRemover::robustRemove($testDir, 3, 100);
if ($result['success']) {
echo "删除成功: " . $result['message'] . "<br>";
} else {
echo "删除失败: " . $result['message'] . "<br>";
}
// 批量删除示例
echo "<br>批量删除示例:<br>";
$dirs = [
'/tmp/batch1',
'/tmp/batch2',
'/tmp/batch3'
];
// 创建测试目录
foreach ($dirs as $dir) {
if (!is_dir($dir)) {
mkdir($dir, 0755);
file_put_contents($dir . "/test.txt", "测试");
}
}
$batchResults = RobustDirectoryRemover::batchRemove($dirs);
foreach ($batchResults as $index => $result) {
echo "删除 {$dirs[$index]}: " . ($result['success'] ? '成功' : '失败') . "<br>";
}
// 排除删除示例
echo "<br>排除删除示例:<br>";
$excludeDir = "/tmp/exclude_test";
if (!is_dir($excludeDir)) {
mkdir($excludeDir, 0755);
// 创建一些文件和目录
file_put_contents($excludeDir . "/delete_me.txt", "删除我");
file_put_contents($excludeDir . "/keep_me.txt", "保留我");
mkdir($excludeDir . "/delete_dir", 0755);
mkdir($excludeDir . "/keep_dir", 0755);
// 删除但保留特定文件/目录
$exclusions = ['keep_me.txt', 'keep_dir'];
if (RobustDirectoryRemover::removeWithExclusions($excludeDir, $exclusions)) {
echo "排除删除执行完成<br>";
// 检查结果
$remaining = scandir($excludeDir);
$remaining = array_diff($remaining, ['.', '..']);
echo "保留的项目: " . implode(', ', $remaining) . "<br>";
// 清理
deleteDirectory($excludeDir);
}
}
?>
<?php
/**
* 跨平台的目录删除工具类
*/
class CrossPlatformDirectoryRemover {
/**
* 删除目录(处理平台差异)
*/
public static function remove($dir) {
$dir = self::normalizePath($dir);
if (!is_dir($dir)) {
return false;
}
// 递归删除目录内容
return self::recursiveRemove($dir);
}
/**
* 标准化路径
*/
private static function normalizePath($path) {
// 统一路径分隔符
$path = str_replace('\\', '/', $path);
// 处理多个连续的路径分隔符
$path = preg_replace('#/+#', '/', $path);
return $path;
}
/**
* 递归删除目录
*/
private static function recursiveRemove($dir) {
if (!is_dir($dir)) {
return false;
}
$items = scandir($dir);
if ($items === false) {
return false;
}
foreach ($items as $item) {
if ($item === '.' || $item === '..') {
continue;
}
$path = $dir . '/' . $item;
if (is_dir($path)) {
if (!self::recursiveRemove($path)) {
return false;
}
} else {
if (!unlink($path)) {
return false;
}
}
}
return rmdir($dir);
}
/**
* 删除目录但保留结构(只删除文件)
*/
public static function removeFilesOnly($dir) {
if (!is_dir($dir)) {
return false;
}
$items = scandir($dir);
if ($items === false) {
return false;
}
foreach ($items as $item) {
if ($item === '.' || $item === '..') {
continue;
}
$path = $dir . '/' . $item;
if (is_dir($path)) {
// 递归处理子目录
self::removeFilesOnly($path);
} else {
// 只删除文件
unlink($path);
}
}
return true;
}
/**
* 删除空目录(清理空目录结构)
*/
public static function removeEmptyDirectories($dir) {
if (!is_dir($dir)) {
return false;
}
$items = scandir($dir);
if ($items === false) {
return false;
}
$hasContent = false;
foreach ($items as $item) {
if ($item === '.' || $item === '..') {
continue;
}
$path = $dir . '/' . $item;
if (is_dir($path)) {
// 递归处理子目录
if (self::removeEmptyDirectories($path)) {
// 子目录被删除,继续检查
} else {
$hasContent = true;
}
} else {
$hasContent = true;
}
}
// 如果目录没有内容,删除它
if (!$hasContent) {
return rmdir($dir);
}
return false;
}
/**
* 获取目录大小后删除
*/
public static function removeWithSizeCheck($dir, $maxSizeMB = null) {
if (!is_dir($dir)) {
return [
'success' => false,
'message' => "目录不存在: $dir",
'size_before' => 0
];
}
// 计算目录大小
$size = self::getDirectorySize($dir);
$sizeMB = round($size / (1024 * 1024), 2);
// 检查大小限制
if ($maxSizeMB !== null && $sizeMB > $maxSizeMB) {
return [
'success' => false,
'message' => "目录大小 {$sizeMB}MB 超过限制 {$maxSizeMB}MB",
'size_before' => $sizeMB
];
}
// 删除目录
if (self::remove($dir)) {
return [
'success' => true,
'message' => "目录删除成功,释放 {$sizeMB}MB 空间",
'size_before' => $sizeMB
];
} else {
return [
'success' => false,
'message' => "目录删除失败",
'size_before' => $sizeMB
];
}
}
/**
* 计算目录大小
*/
private static function getDirectorySize($dir) {
$size = 0;
if (!is_dir($dir)) {
return $size;
}
$items = scandir($dir);
if ($items === false) {
return $size;
}
foreach ($items as $item) {
if ($item === '.' || $item === '..') {
continue;
}
$path = $dir . '/' . $item;
if (is_dir($path)) {
$size += self::getDirectorySize($path);
} else {
$size += filesize($path);
}
}
return $size;
}
}
// 使用示例
echo "<h4>跨平台目录删除示例</h4>";
// 1. 基本删除
$testDir1 = "/tmp/cross_test1";
if (!is_dir($testDir1)) {
mkdir($testDir1, 0755, true);
file_put_contents($testDir1 . "/test.txt", "测试内容");
}
$result1 = CrossPlatformDirectoryRemover::remove($testDir1);
echo "基本删除: " . ($result1 ? '成功' : '失败') . "<br>";
// 2. 只删除文件
$testDir2 = "/tmp/cross_test2";
if (!is_dir($testDir2)) {
mkdir($testDir2, 0755, true);
file_put_contents($testDir2 . "/file1.txt", "文件1");
file_put_contents($testDir2 . "/file2.txt", "文件2");
mkdir($testDir2 . "/subdir", 0755);
file_put_contents($testDir2 . "/subdir/file3.txt", "文件3");
}
$result2 = CrossPlatformDirectoryRemover::removeFilesOnly($testDir2);
echo "只删除文件: " . ($result2 ? '成功' : '失败') . "<br>";
// 检查结果
if (is_dir($testDir2)) {
$items = scandir($testDir2);
$items = array_diff($items, ['.', '..']);
echo "保留的目录结构: " . count($items) . " 个项目<br>";
// 清理
CrossPlatformDirectoryRemover::remove($testDir2);
}
// 3. 删除空目录
$testDir3 = "/tmp/cross_test3";
if (!is_dir($testDir3)) {
mkdir($testDir3 . "/level1/level2/level3", 0755, true);
// 只创建空目录结构
}
// 在level2创建一个文件
file_put_contents($testDir3 . "/level1/level2/test.txt", "测试文件");
$result3 = CrossPlatformDirectoryRemover::removeEmptyDirectories($testDir3);
echo "删除空目录: 执行完成<br>";
// 检查哪些目录被删除
echo "检查目录结构:<br>";
function checkDir($dir, $indent = '') {
if (is_dir($dir)) {
echo $indent . basename($dir) . "/<br>";
$items = scandir($dir);
foreach ($items as $item) {
if ($item !== '.' && $item !== '..') {
checkDir($dir . '/' . $item, $indent . ' ');
}
}
} else {
echo $indent . basename($dir) . "<br>";
}
}
checkDir($testDir3);
// 清理
CrossPlatformDirectoryRemover::remove($testDir3);
// 4. 带大小检查的删除
$testDir4 = "/tmp/cross_test4";
if (!is_dir($testDir4)) {
mkdir($testDir4, 0755, true);
// 创建一个大文件
$fp = fopen($testDir4 . "/bigfile.txt", 'w');
for ($i = 0; $i < 10000; $i++) {
fwrite($fp, str_repeat('x', 1024)); // 写入10MB数据
}
fclose($fp);
}
$result4 = CrossPlatformDirectoryRemover::removeWithSizeCheck($testDir4, 5); // 限制5MB
echo "<br>带大小检查的删除: " . $result4['message'] . "<br>";
if (!$result4['success']) {
// 如果因为大小限制失败,手动删除
CrossPlatformDirectoryRemover::remove($testDir4);
}
?>
| 错误现象 | 可能原因 | 解决方法 |
|---|---|---|
| Warning: rmdir(): Permission denied | PHP进程没有删除目录的权限 | 检查目录权限,确保PHP进程有写入权限 |
| Warning: rmdir(): Directory not empty | 目录不为空,包含文件或子目录 | 先递归删除目录中的所有内容 |
| Warning: rmdir(): No such file or directory | 目录不存在或路径错误 | 使用 is_dir() 检查目录是否存在 |
| Warning: rmdir(): Operation not permitted | 目录正在被使用或受保护 | 检查目录是否被其他进程锁定,或是否为系统目录 |
| 符号链接问题 | 路径指向符号链接 | 使用 is_link() 检查,unlink() 删除符号链接 |
| 跨设备删除失败 | 目录跨越不同文件系统 | 确保递归删除时不会跨越挂载点 |
is_dir() 检查,避免不必要的错误当需要删除多个目录时,按深度逆序排序,先删除最深的目录,可以减少递归调用的开销。
对于大型目录的删除,考虑使用队列或异步任务,避免阻塞主进程。
删除大型目录时,提供进度反馈,让用户知道操作正在进行。
只删除需要的内容,避免不必要的文件系统操作。