PHP bir dizin ağacı ile özyineleme

4 Cevap php

En az 4 veya 5 düzeyde bir derinliğe sahip klasörler kümesi vardır. Ben derin gider olarak dizin ağacında özyineleme ve her dosyayı üzerinde yineleme için arıyorum. Ben dizinlerinin ilk kümeleri içine inmek için kod kazanılmış, ama hiçbir derin, ve ben neden emin değilim ettik. Herhangi bir fikir?

$count = 0;
$dir = "/Applications/MAMP/htdocs/site.com";
function recurseDirs($main, $count){
    $dir = "/Applications/MAMP/htdocs/site.com";
    $dirHandle = opendir($main);
    echo "here";
    while($file = readdir($dirHandle)){
        if(is_dir($file) && $file != '.' && $file != '..'){
            echo "isdir";
            recurseDirs($file);
        }
        else{
            $count++;
            echo "$count: filename: $file in $dir/$main \n<br />";
        }
    }
}
recurseDirs($dir, $count);

4 Cevap

Is_dir çağrı ve recurseDirs tam olarak doğru değildir. Ayrıca sayma doğru işe yaramadı. Bu benim için çalışıyor:

$dir = "/usr/";
function recurseDirs($main, $count=0){
    $dirHandle = opendir($main);
    while($file = readdir($dirHandle)){
        if(is_dir($main.$file."/") && $file != '.' && $file != '..'){
            echo "Directory {$file}: <br />";
            $count = recurseDirs($main.$file."/",$count); // Correct call and fixed counting
        }
        else{
            $count++;
            echo "$count: filename: $file in $main \n<br />";
        }
    }
    return $count;
}
$number_of_files = recurseDirs($dir);

Yukarıdaki işlevi ve fonksiyonu yeni dönüş değeri değişti aramaları dikkat edin.

Yeni Çıkış RecursiveDirectoryIterator.

Eğer arama sonuçları ve diğer şeyler sipariş edilemez, ama sadece dosyaların bir listesini almak gibi mükemmel olmaktan uzak hala, bu iyi.

Bu gibi kılavuzda başlamak için basit örnekler vardır:

<?php

$path = realpath('/etc');

$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), 
RecursiveIteratorIterator::SELF_FIRST);

foreach($objects as $name => $object){
    echo "$name\n";
}

?>

Çağrısı bir hata var

recurseDirs($file);

ve

is_dir($file)

Eğer tam yol vermek zorunda:

recurseDirs($main . '/' .$file, $count);

ve

is_dir($main . '/' .$file)

Ancak, diğer anwerers gibi, ben RecursiveDirectoryIteretor kullanmanızı öneririm.

Yani evet: Bugün listeleyen bir recursive dizin için bir çerez kesici çözüm için tembel ve Googled olmak ve bu genelinde geldi. (Ben bile bu beni aşıyor için Google'a zaman geçirdim neden olarak - Ben her zaman uygun bir nedenle yeniden icat tekerlek için ihtiyacı hissediyorum gibi) kendi işlevi yazma sona erdi olarak benim take paylaşmak eğimli hissettim bu konuda.

Ve RecursiveDirectoryIterator kullanımına karşı görüşler olsa da, ben sadece basit bir ardışık dizin fonksiyonu almak benim gönderebilir ve RecursiveDirectoryIterator üzerinde şıngırdayan siyasetini kaçınmak gerekir.

İşte:

function recursiveDirectoryList( $root )
{

    /* 
     * this next conditional isn't required for the code to function, but I
     * did not want double directory separators in the resulting array values 
     * if a trailing directory separator was provided in the root path;
     * this seemed an efficient manner to remedy said problem easily...
     */
    if( substr( $root, -1 ) === DIRECTORY_SEPARATOR )
    {
        $root = substr( $root, 0, strlen( $root ) - 1 );
    }

    if( ! is_dir( $root ) ) return array();

    $files = array();
    $dir_handle = opendir( $root );

    while( ( $entry = readdir( $dir_handle ) ) !== false )
    {

        if( $entry === '.' || $entry === '..' ) continue;

        if( is_dir( $root . DIRECTORY_SEPARATOR . $entry ) )
        {
            $sub_files = recursiveDirectoryList( 
                $root . 
                DIRECTORY_SEPARATOR . 
                $entry . 
                DIRECTORY_SEPARATOR 
            );
            $files = array_merge( $files, $sub_files );
        }
        else
        {
            $files[] = $root . DIRECTORY_SEPARATOR . $entry;
        }
    }

    return (array) $files;

}

Bu fonksiyon ile, bir dosya sayısını elde etmek gibi cevap basit:

$dirpath = '/your/directory/path/goes/here/';

$files = recursiveDirectoryList( $dirpath );

$number_of_files = sizeof( $files );

Ancak, ilgili dosya yolları bir dizi yükünü istemiyorsanız - veya sadece gerekmez - tavsiye edilmiştir özyinelemeli işlevine sayısını geçmesine gerek yoktur.

Bir gibi sayma gerçekleştirmek için benim özgün fonksiyonunu basit bir değişiklik olabilir:

function recursiveDirectoryListC( $root )
{

    $count = 0;

    if( ! is_dir( $root ) ) return (int) $count;

    $dir_handle = opendir( $root );

    while( ( $entry = readdir( $dir_handle ) ) !== false )
    {

        if( $entry === '.' || $entry === '..' ) continue;

        if( is_dir( $root . DIRECTORY_SEPARATOR . $entry ) )
        {
            $count += recursiveDirectoryListC(
                $root .
                DIRECTORY_SEPARATOR .
                $entry .
                DIRECTORY_SEPARATOR
            );
        }
        else
        {
            $count++;
        }

    }

    return (int) $count;

}

Bu fonksiyonların her ikisi de opendir () işlevi gerçekten dizin okunamadığından veya başka bir hata meydana gelmesi durumunda bir koşullu olarak sarılmalıdır. Bu yüzden doğru yaptığınızdan emin olun:

if( ( $dir_handle = opendir( $dir ) ) !== false ) 
{ 
    /* perform directory read logic */ 
}
else
{
    /* do something on failure */
}

Bu birileri yardımcı olur umarım ...