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?

Adrian M.
sumber

Jawaban:

214

Anda dapat menggunakan glob () dengan GLOB_ONLYDIRopsi

atau

$dirs = array_filter(glob('*'), 'is_dir');
print_r( $dirs);
anjing hantu74
sumber
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);
Coreus
sumber
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>';
    }
}
stloc
sumber
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.

Gordon
sumber
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;
keyur0517
sumber
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
Ricardo Canelas
sumber
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
    */
?>
Sanaan Barzinji
sumber
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;
}
Jan-Fokke
sumber
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

Macbric
sumber
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/

Fifi
sumber
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));
Sultan
sumber
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;
}

Theodore R. Smith
sumber
-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;
}
SilbinaryWolf
sumber
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>'

?>
Faisal
sumber
-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)
A-312
sumber
Ini bukan jawaban lengkap, karena tidak bisa dijalankan.
miken32
@ miken32 Ini adalah jawaban lengkap, coba lagi
A-312