2011-11-15 40 views
2

私は配列に再帰的なディレクトリのリストから結果を引き出していますが、より良い(の読み込み速度が速く、ブリーフィングなどがあるかどうかは疑問です))方法。今、私が持っているPHPの配列への再帰的なディレクトリ。相対的に絶対的にマップされる

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へのノードの相対パスを取得する方法?
  • ​​3210、またはreaddir()などのオプションをと指定するといいですか?代替品ですか?

--Question ends--

を( これは多少の時間に敏感な操作です見つけたとき、私は答えでは、いくつかのベンチマークでPHPのディレクトリ再帰に関連する質問を見て、リンクします)

--Possibly不必要な詳細begins--

目的です。私は仮想作業ディレクトリをアプリケーション用に作成しているので、特定のファイルへの呼び出しは実際のファイルにマッピングされます。たとえば:dir1考える

は、仮想作業ディレクトリの「ルート」である、と私たちはマージしたい(私は場合には、誰かが私が実際にをやっているものに基づいて、全体のより良い代替的なアプローチを持って起草しています) dir2で:

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

それはそうのようなアレイもたらすであろう:マージ既存の相対パスが置き換えられ、そしてそれはactuaうに各要素がマッピングされていること

[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 

お知らせlパス。私は単純に、ここでメソッドの抜粋です、ここ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); 
} 
+0

"to"ディレクトリにscript2.phpがあり、出力結果と競合する "dir2"ディレクトリにはありません。直せますか? – hafichuk

+0

おっと、ありがとう@hafichuk - 修正。 – Dan

+0

これはあまり言及する価値がありませんが、PHPを簡単に最適化することはできないので、ループの外側で 'strlen($ base_realpath)+ 1'のような値をキャッシュする価値があります。 'strlen'は単純な' O(1) '演算であると仮定していますが、たくさんの関数呼び出しを行うと、関数呼び出しも加算されます。 – Matthew

答えて

0

再帰的にあなたが代わりに外部プログラムを試すことができます。速くたくさん:)

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 
} 

あなただけがfindコマンドを使用することができます.phpファイルが必要な場合。

find . -name "*.php" 
+0

'tree'は、ほとんどのUNIXシステムではデフォルトでは利用できません。 'find'は(すべてのファイルにマッチする' -name "* .php" 'を省略することもできますが)特に高速になる可能性は低いです。 – duskwuff

関連する問題