項目部署、備份、模板複製等場景常需完整復制目錄樹 (包含子目錄、文件、權限)。PHP 無內置一鍵復制目錄函數,需自行實現遞歸遍歷。
<?php
class CopyPath {
// 遞歸復制目錄
function wm_chief_copypath($o_path, $n_path) {
$handle = opendir($o_path);
if (!file_exists($n_path)) {
$this->wm_chief_createpath($n_path); // 創建目標目錄
}
$i = 0;
while ($file = readdir($handle)) {
$i++;
if ($i == 1 || $i == 2) continue; // 跳過 . 和 ..
$o_item = $o_path . "/" . $file;
$n_item = $n_path . "/" . $file;
if (is_dir($o_item)) { // 判斷是否目錄 (原代碼 strchr 判斷有無 '.' 有缺陷)
$this->wm_chief_copypath($o_item, $n_item); // 遞歸
} else {
$this->wm_chief_copyfile($o_item, $n_item); // 復制文件
}
}
closedir($handle);
return true;
}
function wm_chief_copyfile($o_file, $n_file) {
return copy($o_file, $n_file); // 可增強:檢查返回值、保留權限 chmod
}
function wm_chief_createpath($n_path) {
return mkdir($n_path, 0777, true); // 遞歸創建,權限受 umask 影響
}
}
// 使用示例
$wm_chief = new CopyPath();
$ok = $wm_chief->wm_chief_copypath("admin", "n_admin");
if ($ok) echo "復制完畢";
?>
!(strchr($file, ".")) 錯誤地以“文件名含點”區分文件/目錄。**正確用 is_dir()**。opendir, mkdir, copy 返回值,拋出異常或記錄日誌。chmod($n_file, fileperms($o_file) & 0777) 保留原權限。copy() 會複製鏈接指向的文件內容,若需保留鏈接需用 readlink() + symlink()。RecursiveIteratorIterator)。function copy_dir_recursive(string $src, string $dst): bool {
$dir = new RecursiveDirectoryIterator($src, RecursiveDirectoryIterator::SKIP_DOTS);
$iter = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::SELF_FIRST);
foreach ($iter as $item) {
$target = $dst . DIRECTORY_SEPARATOR . $iter->getSubPathName();
if ($item->isDir()) {
if (!file_exists($target)) mkdir($target, 0777, true);
} else {
copy($item->getPathname(), $target);
}
}
return true;
}
推薦使用成熟庫 (如 Symfony Filesystem, Laravel File) 處理邊界情況。