PHP Dapatkan semua subdirektori dari direktori tertentu


144

Bagaimana saya bisa mendapatkan semua sub-direktori dari direktori tertentu tanpa file, .(direktori saat ini) atau ..(direktori induk) dan kemudian menggunakan setiap direktori dalam suatu fungsi?

Jawaban:


214

Anda dapat menggunakan glob () dengan GLOB_ONLYDIRopsi

atau

$dirs = array_filter(glob('*'), 'is_dir');
print_r( $dirs);

yang memberikan subdirektori juga?
Gordon

2
Anda harus melakukan resurion di sini
Josef Sábl

5
@developerbmw Catat kata atau . Dia menyajikan dua metode berbeda untuk mencapai tujuan.
Ken Wayne VanderLinde

8
Meskipun pendekatan yang bagus dan sederhana, jawaban yang diterima tidak menjawab pertanyaan: mendapatkan sub-direktori dari direktori induk (alias saudara kandung dari direktori kerja saat ini). Untuk melakukannya perlu mengubah direktori kerja ke direktori induk.
ryanm

1
Ini mengabaikan direktori yang dimulai dengan titik, yaitu. ".config"
blade

159

Berikut adalah bagaimana Anda hanya dapat mengambil direktori dengan GLOB:

$directories = glob($somePath . '/*' , GLOB_ONLYDIR);

2
Ini juga termasuk direktori utama.
pengguna4951

3
Ini tidak termasuk direktori utama dalam kasus saya (Windows)
marcovtwout

1
Ini tidak termasuk direktori utama untuk saya di mac linux juga. Mungkin ada hubungannya dengan jalur yang digunakan?
Jake

1
Ini termasuk juga jalur $somePathdalam output
The Godfather

49

Kelas Spl DirectoryIterator menyediakan antarmuka sederhana untuk melihat konten direktori sistem file.

$dir = new DirectoryIterator($path);
foreach ($dir as $fileinfo) {
    if ($fileinfo->isDir() && !$fileinfo->isDot()) {
        echo $fileinfo->getFilename().'<br>';
    }
}

27

Hampir sama dengan pertanyaan Anda sebelumnya :

$iterator = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator($yourStartingPath), 
            RecursiveIteratorIterator::SELF_FIRST);

foreach($iterator as $file) {
    if($file->isDir()) {
        echo strtoupper($file->getRealpath()), PHP_EOL;
    }
}

Ganti strtoupperdengan fungsi yang Anda inginkan.


1
Terima kasih banyak! satu pertanyaan lagi: bagaimana saya bisa memisahkan hanya nama sub-dir dari seluruh jalur?
Adrian M.

@Adrian Silakan lihat dokumentasi API yang saya berikan di pertanyaan Anda yang lain. getFilename()hanya akan mengembalikan nama direktori.
Gordon

1
Untuk menghilangkan titik-titik tersebut, saya harus menambahkan RecursiveDirectoryIterator::SKIP_DOTSsebagai argumen kedua ke RecursiveDirectoryIteratorkonstruktor.
colan

5

Coba kode ini:

<?php
$path = '/var/www/html/project/somefolder';

$dirs = array();

// directory handle
$dir = dir($path);

while (false !== ($entry = $dir->read())) {
    if ($entry != '.' && $entry != '..') {
       if (is_dir($path . '/' .$entry)) {
            $dirs[] = $entry; 
       }
    }
}

echo "<pre>"; print_r($dirs); exit;

5

Dalam Array:

function expandDirectoriesMatrix($base_dir, $level = 0) {
    $directories = array();
    foreach(scandir($base_dir) as $file) {
        if($file == '.' || $file == '..') continue;
        $dir = $base_dir.DIRECTORY_SEPARATOR.$file;
        if(is_dir($dir)) {
            $directories[]= array(
                    'level' => $level
                    'name' => $file,
                    'path' => $dir,
                    'children' => expandDirectoriesMatrix($dir, $level +1)
            );
        }
    }
    return $directories;
}

//mengakses:

$dir = '/var/www/';
$directories = expandDirectoriesMatrix($dir);

echo $directories[0]['level']                // 0
echo $directories[0]['name']                 // pathA
echo $directories[0]['path']                 // /var/www/pathA
echo $directories[0]['children'][0]['name']  // subPathA1
echo $directories[0]['children'][0]['level'] // 1
echo $directories[0]['children'][1]['name']  // subPathA2
echo $directories[0]['children'][1]['level'] // 1

Contoh untuk menunjukkan semua:

function showDirectories($list, $parent = array())
{
    foreach ($list as $directory){
        $parent_name = count($parent) ? " parent: ({$parent['name']}" : '';
        $prefix = str_repeat('-', $directory['level']);
        echo "$prefix {$directory['name']} $parent_name <br/>";  // <-----------
        if(count($directory['children'])){
            // list the children directories
            showDirectories($directory['children'], $directory);
        }
    }
}

showDirectories($directories);

// pathA
// - subPathA1 (parent: pathA)
// -- subsubPathA11 (parent: subPathA1)
// - subPathA2 
// pathB
// pathC

2
<?php
    /*this will do what you asked for, it only returns the subdirectory names in a given
      path, and you can make hyperlinks and use them:
    */

    $yourStartingPath = "photos\\";
    $iterator = new RecursiveIteratorIterator( 
        new RecursiveDirectoryIterator($yourStartingPath),  
        RecursiveIteratorIterator::SELF_FIRST);

    foreach($iterator as $file) { 
        if($file->isDir()) { 
            $path = strtoupper($file->getRealpath()) ; 
            $path2 = PHP_EOL;
            $path3 = $path.$path2;

            $result = end(explode('/', $path3)); 

            echo "<br />". basename($result );
        } 
    } 

    /* best regards,
        Sanaan Barzinji
        Erbil
    */
?>

2

Anda dapat mencoba fungsi ini (diperlukan PHP 7)

function getDirectories(string $path) : array
{
    $directories = [];
    $items = scandir($path);
    foreach ($items as $item) {
        if($item == '..' || $item == '.')
            continue;
        if(is_dir($path.'/'.$item))
            $directories[] = $item;
    }
    return $directories;
}

1

Cara yang sesuai

/**
 * Get all of the directories within a given directory.
 *
 * @param  string  $directory
 * @return array
 */
function directories($directory)
{
    $glob = glob($directory . '/*');

    if($glob === false)
    {
        return array();
    }

    return array_filter($glob, function($dir) {
        return is_dir($dir);
    });
}

Terinspirasi oleh Laravel


1
Ini tampaknya berlebihan ketika ada sebuah bendera GLOB_ONLYDIR, lihat php.net/manual/en/function.glob.php
Robert Pounder

1

Fungsi rekursif berikut mengembalikan larik dengan daftar lengkap sub direktori

function getSubDirectories($dir)
{
    $subDir = array();
    $directories = array_filter(glob($dir), 'is_dir');
    $subDir = array_merge($subDir, $directories);
    foreach ($directories as $directory) $subDir = array_merge($subDir, getSubDirectories($directory.'/*'));
    return $subDir;
}

Sumber: https://www.lucidar.me/en/web-dev/how-to-get-subdirectories-in-php/


Pertanyaan itu tidak meminta rekursi. Hanya daftar direktori dalam direktori tertentu, yang diberikan kepada mereka pada tahun 2010.
miken32

0

Ini adalah kode satu baris:

 $sub_directories = array_map('basename', glob($directory_path . '/*', GLOB_ONLYDIR));

0

Daftar Direktori Non-rekursif Saja

Satu-satunya pertanyaan yang langsung menanyakan ini telah ditutup secara keliru, jadi saya harus meletakkannya di sini.

Ini juga memberikan kemampuan untuk memfilter direktori.

/**
 * Copyright © 2020 Theodore R. Smith <https://www.phpexperts.pro/>
 * License: MIT
 *
 * @see https://stackoverflow.com/a/61168906/430062
 *
 * @param string $path
 * @param bool   $recursive Default: false
 * @param array  $filtered  Default: [., ..]
 * @return array
 */
function getDirs($path, $recursive = false, array $filtered = [])
{
    if (!is_dir($path)) {
        throw new RuntimeException("$path does not exist.");
    }

    $filtered += ['.', '..'];

    $dirs = [];
    $d = dir($path);
    while (($entry = $d->read()) !== false) {
        if (is_dir("$path/$entry") && !in_array($entry, $filtered)) {
            $dirs[] = $entry;

            if ($recursive) {
                $newDirs = getDirs("$path/$entry");
                foreach ($newDirs as $newDir) {
                    $dirs[] = "$entry/$newDir";
                }
            }
        }
    }

    return $dirs;
}



-1

Temukan semua file PHP secara rekursif. Logikanya harus cukup sederhana untuk di-tweak dan bertujuan untuk menjadi cepat (er) dengan menghindari pemanggilan fungsi.

function get_all_php_files($directory) {
    $directory_stack = array($directory);
    $ignored_filename = array(
        '.git' => true,
        '.svn' => true,
        '.hg' => true,
        'index.php' => true,
    );
    $file_list = array();
    while ($directory_stack) {
        $current_directory = array_shift($directory_stack);
        $files = scandir($current_directory);
        foreach ($files as $filename) {
            //  Skip all files/directories with:
            //      - A starting '.'
            //      - A starting '_'
            //      - Ignore 'index.php' files
            $pathname = $current_directory . DIRECTORY_SEPARATOR . $filename;
            if (isset($filename[0]) && (
                $filename[0] === '.' ||
                $filename[0] === '_' ||
                isset($ignored_filename[$filename])
            )) 
            {
                continue;
            }
            else if (is_dir($pathname) === TRUE) {
                $directory_stack[] = $pathname;
            } else if (pathinfo($pathname, PATHINFO_EXTENSION) === 'php') {
                $file_list[] = $pathname;
            }
        }
    }
    return $file_list;
}

Pertanyaan tidak menanyakan daftar file, atau rekursi apa pun. Hanya daftar direktori dalam direktori tertentu.
miken32

Saya sangat sadar. Pada saat itu, saya yakin ini adalah jawaban teratas di Google atau serupa, jadi saya menambahkan solusi saya untuk mereka yang mencari implementasi rekursif yang tidak merusak tumpukan. Saya tidak melihat ada salahnya memberikan sesuatu yang dapat ditebang untuk menyelesaikan masalah aslinya.
SilbinaryWolf

-1

Jika Anda mencari solusi daftar direktori rekursif. Gunakan kode di bawah ini. Saya harap ini dapat membantu Anda.

<?php
/**
 * Function for recursive directory file list search as an array.
 *
 * @param mixed $dir Main Directory Path.
 *
 * @return array
 */
function listFolderFiles($dir)
{
    $fileInfo     = scandir($dir);
    $allFileLists = [];

    foreach ($fileInfo as $folder) {
        if ($folder !== '.' && $folder !== '..') {
            if (is_dir($dir . DIRECTORY_SEPARATOR . $folder) === true) {
                $allFileLists[$folder . '/'] = listFolderFiles($dir . DIRECTORY_SEPARATOR . $folder);
            } else {
                $allFileLists[$folder] = $folder;
            }
        }
    }

    return $allFileLists;
}//end listFolderFiles()


$dir = listFolderFiles('your searching directory path ex:-F:\xampp\htdocs\abc');
echo '<pre>';
print_r($dir);
echo '</pre>'

?>

-2

Temukan semua file dan folder di bawah direktori tertentu.

function scanDirAndSubdir($dir, &$fullDir = array()){
    $currentDir = scandir($dir);

    foreach ($currentDir as $key => $val) {
        $realpath = realpath($dir . DIRECTORY_SEPARATOR . $val);
        if (!is_dir($realpath) && $filename != "." && $filename != "..") {
            scanDirAndSubdir($realpath, $fullDir);
            $fullDir[] = $realpath;
        }
    }

    return $fullDir;
}

var_dump(scanDirAndSubdir('C:/web2.0/'));

Sampel :

array (size=4)
  0 => string 'C:/web2.0/config/' (length=17)
  1 => string 'C:/web2.0/js/' (length=13)
  2 => string 'C:/web2.0/mydir/' (length=16)
  3 => string 'C:/web2.0/myfile/' (length=17)

Ini bukan jawaban lengkap, karena tidak bisa dijalankan.
miken32

@ miken32 Ini adalah jawaban lengkap, coba lagi
A-312
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.