2011-11-30 18 views
27

mi sono imbattuto in alcuni articoli su prestazioni e readdir qui è lo script php:php cartella ricorsiva readdir vs prestazioni ritrovamento

function getDirectory($path = '.', $level = 0) { 
    $ignore = array('cgi-bin', '.', '..'); 
    $dh = @opendir($path); 
    while(false !== ($file = readdir($dh))){ 
     if(!in_array($file, $ignore)){ 
      $spaces = str_repeat(' ', ($level * 4)); 
      if(is_dir("$path/$file")){ 
       echo "$spaces $file\n"; 
       getDirectory("$path/$file", ($level+1)); 
      } else { 
       echo "$spaces $file\n"; 
      } 
     } 
    } 
    closedir($dh); 
} 
getDirectory("."); 

questa eco correttamente i file/cartelle.

ora ho trovato questo:

$t = system('find'); 
print_r($t); 

che trovano anche tutte le cartelle ei file allora posso creare una matrice come il primo codice.

penso che il system('find'); è più veloce rispetto alla readdir ma voglio sapere se si tratta di una buona pratica? grazie mille

+8

Una chiamata di sistema non è certamente portatile. Il tuo codice di esempio dipende da un * nix OS. – nickb

+0

ho centos 5 con apache e php + mysql che va bene? – rcs20

+1

È anche una cattiva idea abituarsi all'uso delle chiamate 'system()'. Dovrebbero andare bene senza parametri, ma se li costruisci dinamicamente in base all'input dell'utente, è probabile che crei buchi di sicurezza. – millimoose

risposta

35

Ecco il mio punto di riferimento utilizzando un semplice ciclo for con 10 iterazione sul mio server:

$path = '/home/clad/benchmark/'; 
// this folder has 10 main directories and each folder as 220 files in each from 1kn to 1mb 

// glob no_sort = 0.004 seconds but NO recursion 
$files = glob($path . '/*', GLOB_NOSORT); 

// 1.8 seconds - not recommended 
exec('find ' . $path, $t); 
unset($t); 

// 0.003 seconds 
if ($handle = opendir('.')) { 
while (false !== ($file = readdir($handle))) { 
    if ($file != "." && $file != "..") { 
    // action 
    } 
} 
closedir($handle); 
} 

// 1.1 seconds to execute 
$path = realpath($path); 
$objects = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST); 
    foreach($objects as $name => $object) { 
    // action 
    } 
} 

Chiaramente il readdir è più veloce da usare soprattutto se si dispone di un sacco di traffico sul tuo sito.

+8

niente di meglio di un punto di riferimento! bel lavoro – joel

+2

Buona risposta, ma mi manca qualcosa ... la soluzione 'readdir()' da sola non è ricorsiva. Questo non distorcerà i risultati? –

+0

Come confrontare le singole funzioni come te, aki? – kolja

2

'find' non è portatile, è un comando unix/linux. readdir() è portatile e funzionerà su Windows o qualsiasi altro sistema operativo. Inoltre, 'find' senza parametri è ricorsivo, quindi se sei in una dir con molti sottodir e file, vedrai tutti loro, piuttosto che solo il contenuto di quel $ path.

+0

Anche se vedo che la tua funzione è anch'essa ricorsiva, quindi ignori il rant in merito alla ricorsività. Nota, tuttavia, anche l'output di "trova" è formattato in un modo particolare. – favoretti

+0

non ho mai usato Windows quindi è solo unix o linux, per il formating posso occuparmi di – rcs20

+2

Bene, mettiamola così. In termini di velocità, non importa molto, ma per controllare il comportamento della funzione utilizzando find - sarà necessario modificare i parametri della riga di comando "find" anziché utilizzare il modo in codice per controllare il comportamento della funzione. Io, per esempio, non andrei con find, a meno che non ci fosse una ragione molto specifica per farlo. – favoretti