Exec — эквивалентно Windows XCopy на PHP?

Я конвертирую старую систему из пакетных файлов Windows в php для запуска на Debian Box. Я столкнулся с некоторыми вьющимися командами 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 — Как рекурсивно копировать структуру папок, только копируя соответствующие файлы, которые существуют в структуре назначения.

Я предполагаю, что мне придется использовать exec () из php, но не уверен, что я должен работать. Любые указатели оценили 🙂

1

Решение

Просто чтобы дать вам подсказку о правильном направлении, я бы начал с Компонент командной строки Symfony

Затем вы можете закодировать ключи в -q или —quiet вместо / Q и затем построить логику с помощью php файл функции.

Сказав все это, если вы действительно не хотите забавного упражнения по кодированию php, вероятно, было бы лучше использовать скрипт bash или аналогичный и использовать команду cp.

0

Другие решения

Хм, другой проект, та же проблема и снова нашел свой вопрос! Вот что я сделал на этот раз (где 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);
}
}
}

Здесь есть несколько заметных пробелов, особенно в том, что здесь нет обработки исключений, но на этот раз это избавило меня от неприятностей.

0

По вопросам рекламы [email protected]