В настоящее время я использую следующий код для перечисления всех подкаталогов в определенном каталоге.
$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 />";
}
}
Ваш пример использует RecursiveIteratorIterator::SELF_FIRST
флаг, который списки листьев и родителей в итерации с родителями, идущими первыми (из документов).
Это означает, что с такой структурой каталогов:
foo/
foo/bar/
foo/bar/bat.txt
Порядок итерации от родителей к листьям:
Это может быть проблематично, как вы уже отметили.
Для ваших нужд RecursiveIteratorIterator::CHILD_FIRST
Флаг должен быть использован. Этот флаг указывает итератору идти в другом направлении, от листьев к родителям.
Вы можете хранить все каталоги в массиве, и после этого вы можете зацикливать массив в порядке убывания, изменяя последнюю папку на верхний регистр.
Вот пример:
$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);
}