Как вычислить наименьший общий знаменатель из набора путей и символических ссылок в PHP?

Я получаю массив путей (в сочетании с настройками по умолчанию и пользовательскими настройками) и мне нужно выполнить рекурсивный поиск некоторых файлов данных, которые могут быть скрыты между десятками тысяч файлов в любом из этих путей.

Я делаю рекурсивный поиск с RecursiveDirectoryIterator но это довольно медленно и предлагаемая альтернатива exec("find") еще медленнее. Чтобы сэкономить время, ввод / вывод и вычислительную мощность, я хотел бы заранее выполнить некоторую предварительную обработку, чтобы избежать многократного поиска в деревьях каталогов и вычисления наименьшего общего знаменателя из заданных путей. Буду признателен за любые советы о том, как это сделать.

Подвох заключается в том, что любой из данных путей может быть не только предком других или просто символической ссылкой друг на друга, но может быть задан как реальный путь или путь к символической ссылке. По крайней мере, можно предположить, что не будет никаких кружащихся символических ссылок (хотя проверка не будет плохой).

Мне нужно реализовать это в PHP, и я набросал следующий код, который еще не охватывает все случаи.

// make all given paths absolute and resolve symlinks
$search_paths = array_map( function($path) {
return realpath( $path ) ?: $path;
}, $search_paths );

// remove all double entries
$search_paths = array_unique( $search_paths );

// sort by length of path, shortest first
usort($search_paths, function($a, $b) {
return strlen($a) - strlen($b);
});

// iterate over all paths but the last
for ( $i = 0; $i < count( $search_paths ) - 1; $i++ ) {
// iterate over all paths following the current
for ( $j = $i; $j < count( $search_paths ); $j++ ) {
if ( strpos ( $search_paths[$j], $search_paths[$i] ) === 0 ) {
// longer path starts with shorter one, thus it's a child. Nuke it!
unset( $search_paths[$j] );
}
}
}

Где этот код не хватает:
Вообразите эти пути в $search_paths

/e/f
/a/b/c/d
/e/f/g/d

с /e/f/g/d будучи символической ссылкой на /a/b/c/d,

Код выше оставил бы эти два:

/e/f
/a/b/c/d

но в поисках /e/f будет на самом деле достаточно, так как он охватывает /a/b/c/d через символическую ссылку /e/f/g/d, Это может звучать как крайний случай, но на самом деле вполне вероятно в моей ситуации.

Хитрый, а?

Я уверен, что я не единственный, кто столкнулся с этой проблемой, но я не смог найти решение с помощью Google. Может быть, я просто не понимаю правильную формулировку проблемы.

Спасибо за чтение этого далеко! 🙂

0

Решение

Задача ещё не решена.

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

Других решений пока нет …

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