首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 遞歸複製整個目錄的工具類

     編輯:PHP 綜合知識

應用場景

部署發布、模板複製、備份同步等場景常需將整個目錄結構(含子目錄、文件)完整複製到新位置。PHP 原生無單一函數實現,需自行封裝遞歸邏輯。

類設計

  • CopyFile:單一職責,提供 copyFile($src, $dst) 入口;
  • 遞歸創建目錄:CreateFolder() 兼容深層路徑一次性創建;
  • 錯誤抑制:使用 @mkdir 避免已存在時拋出警告。

完整代碼

CreateFolder($toFile);

        $handle = opendir($fromFile);
        if (!$handle) return false;

        while (($item = readdir($handle)) !== false) {
            if ($item === '.' || $item === '..') continue;

            $srcPath = $fromFile . DIRECTORY_SEPARATOR . $item;
            $dstPath = $toFile . DIRECTORY_SEPARATOR . $item;

            if (is_file($srcPath)) {
                // 文件直接複製
                if (!copy($srcPath, $dstPath)) {
                    closedir($handle);
                    return false;
                }
            } elseif (is_dir($srcPath)) {
                // 目錄遞歸
                if (!$this->copyFile($srcPath, $dstPath)) {
                    closedir($handle);
                    return false;
                }
            }
        }
        closedir($handle);
        return true;
    }

    /** 遞歸創建多級目錄
     * @param string $dir 目錄路徑
     * @param int $mode 權限,默認 0777
     * @return bool
     */
    public function CreateFolder($dir, $mode = 0777) {
        if (is_dir($dir) || @mkdir($dir, $mode, true)) {
            return true;
        }
        // 理論上 mkdir($dir, $mode, true) 已支持遞歸創建(PHP 5.0.0+)
        // 此處保留遞歸邏輯兼容極舊版本
        return $this->CreateFolder(dirname($dir), $mode) && @mkdir($dir, $mode);
    }
}

// 使用示例
$copier = new CopyFile();
$success = $copier->copyFile('/var/www/project_a', '/var/www/backup/project_a_20240115');
if ($success) {
    echo "複製完成";
} else {
    echo "複製失敗,請檢查權限或路徑";
}

關鍵點補充

  1. 路徑分隔符:使用 DIRECTORY_SEPARATOR 跨平台兼容(Windows \,Linux /);
  2. mkdir($path, $mode, true) 第三參數 true 即為遞歸創建,PHP 5.0.0+ 內置支持,手動遞歸僅為教學或極舊環境;
  3. 符號鏈接:本實現不處理软鏈接,如需保留鏈接關係需用 readlink() + symlink();
  4. 大文件/海量文件:建議改用 exec('cp -r ...') 或 rsync 系統命令,性能更優;
  5. 進度回調:可增加回調參數 function($current, $total) 實現進度條。

擴展:基於 SPL 的現代寫法

use RecursiveIteratorIterator;
use RecursiveDirectoryIterator;
use FilesystemIterator;

function copyDirSpl($src, $dst) {
    $src = realpath($src);
    $iterator = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($src, FilesystemIterator::SKIP_DOTS),
        RecursiveIteratorIterator::SELF_FIRST
    );

    foreach ($iterator as $item) {
        $relative = substr($item->getPathname(), strlen($src) + 1);
        $target = $dst . DIRECTORY_SEPARATOR . $relative;

        if ($item->isDir()) {
            @mkdir($target, 0777, true);
        } else {
            copy($item->getPathname(), $target);
        }
    }
}

SPL 迭代器代碼更簡潔、性能更好,推薦 PHP 5.3+ 環境使用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved