Переименовать все подкаталоги в каталоге рекурсивно - PullRequest
0 голосов
/ 25 апреля 2018

В настоящее время я использую следующий код для перечисления всех подкаталогов в определенном каталоге.

$dir = realpath('custom_design_copy/');

$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir), RecursiveIteratorIterator::SELF_FIRST);

foreach($objects as $name => $object){
    if(is_dir($object)){
        echo "$name<br />";
    }
}

Это дает мне результаты, которые выглядят примерно так:

C:\Data\Web\custom_design_copy\Product
C:\Data\Web\custom_design_copy\Product\images
C:\Data\Web\custom_design_copy\Product\Scripts

Я хочу переименовать все эти подкаталоги с помощью strtoupper(), чтобы нормализовать все их имена.Мне известна функция rename(), но я боюсь, что, если я попробую следующее:

rename($name, strtoupper($name));

, я изменю одно из имен родительских каталогов custom_design_copy, чего я надеюсь избежать.Как я могу избежать этой проблемы?Я думал об использовании substr() и поиске последнего вхождения «\», чтобы изолировать имя каталога в конце, но для этого должно быть более простое решение.Конечный результат, который я ищу, таков:

C:\Data\Web\custom_design_copy\PRODUCT
C:\Data\Web\custom_design_copy\PRODUCT\IMAGES
C:\Data\Web\custom_design_copy\PRODUCT\SCRIPTS

РЕДАКТИРОВАТЬ: В ожидании совета, я попытался мой первоначальный подход и обнаружил, что он работает.

$dir = realpath('custom_design_copy/');

$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir), RecursiveIteratorIterator::SELF_FIRST);

foreach($objects as $name => $object){
    if(is_dir($object)){
        $slashPos = strrpos($name, '\\');
        $newName  = substr($name, 0, $slashPos + 1) . strtoupper(substr($name, $slashPos + 1));

        rename($name, $newName);

        echo "$name<br />";
    }
}

Ответы [ 2 ]

0 голосов
/ 25 апреля 2018

В вашем примере используется флаг RecursiveIteratorIterator::SELF_FIRST, в котором перечисляет список отпусков и родителей, причем родители идут первыми ( из документов ).

Это означает, чтос такой структурой каталогов, как:

foo/
foo/bar/
foo/bar/bat.txt

Порядок итерации от родителей к листьям:

  1. foo /
  2. foo / bar /
  3. foo / bat / bat.txt

Это может быть проблематично, как вы уже отметили.


Для ваших нужд следует использовать флаг RecursiveIteratorIterator::CHILD_FIRST.Этот флаг указывает итератору двигаться в другом направлении, от листьев к родителям.

  1. foo / bar / bat.txt
  2. foo / bar /
  3. foo/
0 голосов
/ 25 апреля 2018

Вы можете сохранить все каталоги в массиве, а затем зациклить массив в порядке убывания, изменив последнюю папку на верхний регистр.

Вот пример:

$path = 'custom_design_copy' . DIRECTORY_SEPARATOR;

$main_dir = realpath($path);

$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($main_dir), RecursiveIteratorIterator::SELF_FIRST);

foreach ($objects as $name => $object) {

    if ($object->isDir() && !in_array($object->getFilename(), array('.', '..'))) {

        $directories[] = $name;

    }
}

foreach (array_reverse($directories) as $dir) {
    rename($dir, last_path_upper($dir));
}

function last_path_upper($str) {

    $arr = explode(DIRECTORY_SEPARATOR, $str);

    $last = array_pop($arr);

    return join(DIRECTORY_SEPARATOR, $arr) . DIRECTORY_SEPARATOR . strtoupper($last);

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...