Рекурсивный каталог для массива в PHP;относительное сопоставлено с абсолютным - PullRequest
2 голосов
/ 15 ноября 2011

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

path_relative_to_somedir => absolute_path

Прямо сейчас у меня есть:

$map = array();
$base_realpath = realpath('/path/to/dir');
$iterator = new \RecursiveDirectoryIterator($base_realpath);
foreach((new \RecursiveIteratorIterator($iterator)) as $node){
    $node_realpath = $node->getRealpath();
    $map[substr($node_realpath, strlen($base_realpath) + 1)] = $node_realpath;
}

Это прекрасно работает ( на первый взгляд ), но я 'Я обеспокоен крайними случаями, которые, хотя я уверен, что они выйдут на тестирование, другие могут быть в состоянии указать.Итак:

  • Существует ли лучший ( чтение быстрее, точнее, надежнее ) способ получить путь к узлу относительно $base_realpath?
  • Следует ли мне рассматривать варианты, такие как glob() или readdir() как более быстрые альтернативы?( это несколько чувствительная ко времени операция, я видел вопрос, касающийся рекурсии каталогов в PHP с некоторыми тестами в ответе, ссылка будет при обнаружении )

-- Задание заканчивается -


- Возможно, начинается ненужная деталь -

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

Учитывая, что dir1 является «корнем» виртуальногорабочий каталог, и мы хотим объединить в dir2:

path/                       path/
|                           |
+-- to/                     +-- to/
    |                           |
    +-- dir1/                   +-- dir2/
        |                           |
        +-- script1.php             +-- script2.php
        |                           |
        +-- script2.php             +-- subdir/
        |                               | 
        +-- subdir/                     +-- script4.php
            |               
            +-- script3.php 

Это приведет к массиву примерно так:

[script1.php] => path/to/dir1/script1.php
[script2.php] => path/to/dir2/script2.php
[subdir/script3.php] => path/to/dir1/subdir/script3.php
[subdir/script4.php] => path/to/dir2/subdir/script4.php

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

public function mergeModule($name){
    $path = realpath($this->_application->getPath() . 'modules/' . $name);
    if(!is_dir($path) || !is_readable($path)){
        // @todo; throw exception
    }
    $map = array();
    try{
        $directory_iterator = new \RecursiveDirectoryIterator($path);
        foreach((new \RecursiveIteratorIterator($directory_iterator)) as $node){
            $node_realpath = $node->getRealpath();
            $map[substr($node_realpath, strlen($path) + 1)] = $node_realpath;
        }
    }catch(\Exception $exception){
        // @todo; handle
    }
    $this->_map = array_replace($this->_map, $map);
}

1 Ответ

0 голосов
/ 06 января 2012

Если вы ищете более быстрый способ рекурсивного составления списка каталогов, вы можете попробовать использовать внешние программы.Намного быстрее:)

exec('tree -if /var/www',$tree);
foreach($tree as $key => $path) {
    if ( !$path ) // Ignore the summary ex "5 directories, 30 files"
       break;

    // Do something with the file/dir path
}

Если вам нужны только файлы .php, вы можете использовать команду find.

find . -name "*.php"
...