LINUX.ORG.RU

Получение иерархии директории в PHP

 ,


0

1

Есть путь

/a/b/c/d
C:\a\b\c\d
Надо получить иерархический массив
array( 'a' => '/a',
       'b' => '/a/b',
       'c' => '/a/b/c',
       'd' => '/a/b/c/d')

array( 'a' => 'C:\a',
       'b' => 'C:\a\b',
       'c' => 'C:\a\b\c',
       'd' => 'C:\a\b\c\d')
Казалось бы, ничего сложного, но вот вопрос: как определить корень платформонезависимо? Что даст basename('C:\') ? Какие еще могут быть варианты? dirname($path) == '.' ? Или какая-нибудь хитрость что «/..» возвращает в то же место? У меня нет венды под рукой чтобы проверить.

UPDATE: остановился на варианте

$curdir == dirname($curdir)
Буду рад если кто расскажет как такая штука ведет себя в разных осях.

★★★★★

Последнее исправление: morse (всего исправлений: 1)
Ответ на: комментарий от morse

А если не использовать абсолютные пути?

Xenius ★★★★★
()
Ответ на: комментарий от morse

Не хочу воротить платформозафисимого кода

А не получится. Потому что само понятие корня на разных платформах разное.

KRoN73 ★★★★★
()
from os.path import split

def path_as_array(path):
    base, item = split(path)

    if not base:
        return [item]

    if not item:
        return [base]

    array = path_as_array(base)
    array.append(item)

    return array


def print_path(path):
    print("{}\t = {}".format(path, path_as_array(path)))


print_path('/home/user/file')
print_path('user/file')
print_path('/')
print_path('C:/asd')
print_path('C:/')
print_path('C:')
print_path('')

остальное зависит от того что ты дальше с этим путем будешь делать

val-amart ★★★★★
()
Последнее исправление: val-amart (всего исправлений: 1)

Как-то так.

$dir = './';
$iterator = new \RecursiveDirectoryIterator(
	realpath($dir), 
	\FilesystemIterator::CURRENT_AS_SELF
);
function getPaths(\FilesystemIterator $iterator) {
	static $paths = [];
	foreach ($iterator as $key => $item) {
		if ($item->isDot()) {
			continue;
		}
		try {
			$paths[$item->getBasename()] = $key;
			getPaths($item->getChildren());
		} catch (\UnexpectedValueException $e) {
		}
	}
	return $paths;
}
var_dump(getPaths($iterator));
array(5) {
  'a' =>
  string(17) "/home/kilte/tmp/a"
  'b' =>
  string(19) "/home/kilte/tmp/a/b"
  'c' =>
  string(21) "/home/kilte/tmp/a/b/c"
  'd' =>
  string(23) "/home/kilte/tmp/a/b/c/d"
  't.php' =>
  string(21) "/home/kilte/tmp/t.php"
}
Kilte ★★★★★
()
Ответ на: комментарий от KRoN73

Потому что само понятие корня на разных платформах разное.

В моем случае вполне одинаковое: место, выше которого не подняться по иерархии.

morse ★★★★★
() автор топика
Ответ на: комментарий от morse

А про это я ничего не увидел. То есть тебе нужно снизу вверх идти, правильно? Тогда сейчас попробую набросать что-нибудь.

Kilte ★★★★★
()
Ответ на: комментарий от morse

Ну вот, вроде должно работать платформонезависимо:

function test($dir) {
	$result = dirname($dir);
	if ($result == dirname($result)) {
		return $result;
	}
	return test($result);
}
var_dump(test(__DIR__), dirname('/'), dirname('/home'));
string(1) "/"
string(1) "/"
string(1) "/"

Kilte ★★★★★
()

Так и не понял. Зачем вообще определять корень? Если только скрипт лежит не рядом с ними. Но и в таком случае проще воспользоваться относительными путями, а затем, если так уж критично, воспользоваться realpath

Kilte ★★★★★
()
Ответ на: комментарий от Kilte

Ну вот, вроде должно работать платформонезависимо

Ну то есть по сути то же самое: $curdir == dirname($curdir)

Ну тогда будем надеяться.

morse ★★★★★
() автор топика
Ответ на: комментарий от morse

Не заметил апдейта, когда писал. Да будет всё работать. Покрайней мере должно :3

Kilte ★★★★★
()
Ответ на: комментарий от ritsufag

let the fun begin!

чем ужасно? по-моему, просто прекрасен!

val-amart ★★★★★
()

А вообще, если хорошо подумать, то realpath, explode(DIRECTORY_SEPARATOR, path), array_shift что-ли. Ну как-то так. И никаких $curdir == dirname($curdir)

Kilte ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.