【问题标题】:equivalent to windows xcopy on php?相当于php上的windows xcopy?
【发布时间】:2016-05-25 23:46:25
【问题描述】:

我正在将旧系统从 Windows 批处理文件转换为 php,以便在 debian 机器上运行。我遇到了一些 curly xcopy 命令,想知道它们的等效代码在 php 中是什么。

xcopy src dest /Q /R /S /Y /exclude:c:\exclusions.txt

xcopy src dest /C /I /Q /R /S /U /Y /exclude:c:\exclusions.txt

http://ss64.com/nt/xcopy.html 很有帮助地告诉我开关是什么:

/C = continue if error
/I = assume destination is a folder
/Q = quiet (no output)
/R = overwrite read only files
/S = copy folders and subfolders recursively
/U = copy only files that exist in the destination
/Y = supress prompt to overwrite destination file (and assume YES)

c:\exclusions.txt 只需要跳过文件名

.ds_store
thumbs.db
.git
.ssh
.htaccess
README.MD

我最想知道的开关是/U/R/S - 如何递归地复制文件夹结构,只复制目标结构中存在的匹配文件。

我想我必须使用 php 中的 exec(),但不确定我应该运行什么。任何指针表示赞赏:)

【问题讨论】:

  • 查看cp(1) 手册页,或tar/paxrsync 了解更多功能更新。

标签: php exec xcopy


【解决方案1】:

只是为了给你一个正确方向的提示,我将从Symfony command line component开始

然后您可以将开关编码为 -q 或 --quiet 而不是 /Q,然后使用 php 的 file 函数构建逻辑。

说了这么多,除非你真的想在 php 编码中进行有趣的练习,否则最好使用 bash 脚本或类似的脚本并使用 cp 命令。

【讨论】:

  • 是的,即使框架的其余部分在 php 中,当一个体面的命令行选项 exec 在这种情况下可以做同样的事情时,没有理由使用它。感谢 Symfony 指针 :)
【解决方案2】:

嗯,不同的项目,同样的问题,又找到了我自己的问题!这是我这次所做的(cp/rsync 并不总是可用):

// php xcopy, assumes /s /q /c /y /r switches
// /exclude switch via skipfiles and skipfolders (appended to in-built defaults)
// /u switch via $ifindest
public static function xcopy($source, $dest, $skipfiles = [], $skipfolders = [], $ifindest = false) {

    // ensure source and destination end in one directory separator
    $source = rtrim($source,DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
    $dest = rtrim($dest,DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;

    // normalise skip arrays and apply defaults
    $skipfolders = array_unique(array_merge(['.git','.ssh','editor'], array_map('rtrim', $skipfolders, array_fill(0, count($skipfolders), DIRECTORY_SEPARATOR))));
    $skipfiles = array_unique(array_merge(['.ds_store','.htaccess','thumbs.db','about.txt','readme.md'], array_map('strtolower', $skipfiles)));

    // examine folders and files using an iterator to avoid exposing functional recursion
    foreach ($iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST) as $item) {
        $name = strtolower($iterator->getFilename());
        $path = $iterator->getSubPathName();
        $folders = explode(DIRECTORY_SEPARATOR, empty($iterator->getSubPath()) ? $iterator->getSubPathName() : $iterator->getSubPath()); // subpath is empty at source root folder
        $skip = count(array_intersect($folders,$skipfolders))>0;

        // skip this iteration due to a folder match?
        if ($skip) continue;

        // skip this iteration due to a file match?
        if ($item->isFile() && in_array($name, $skipfiles)) continue;

        if ($item->isDir()) {
            if (!file_exists("{$dest}{$path}")) {

                // create destination folder structure
                mkdir($dest.$path,0775,true);
            }
        } else {
            if ($ifindest) {
                if (!file_exists("{$dest}{$path}")) continue; // copy only if file exists in destination already
            }

            // finally we can copy the file
            copy($path,$dest.$path);
        }
    }
}

这里有一些值得注意的漏洞,特别是没有异常处理,但这次它让我摆脱了麻烦。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-23
    • 2010-10-14
    • 2022-01-01
    • 1970-01-01
    • 2010-10-12
    相关资源
    最近更新 更多