PHP Nhận tất cả các thư mục con của một thư mục nhất định


139

Làm thế nào tôi có thể nhận được tất cả các thư mục con của một thư mục nhất định mà không có tệp, .(thư mục hiện tại) hoặc ..(thư mục mẹ) và sau đó sử dụng mỗi thư mục trong một chức năng?

Câu trả lời:


210

bạn có thể sử dụng global () với GLOB_ONLYDIRtùy chọn

hoặc là

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

mà cung cấp cho thư mục con là tốt?
Gordon

2
Bạn phải làm một cuộc hồi sinh ở đây
Josef Sábl

Xin lỗi, tùy chọn GLOB_ONLYDIR ở đâu ??
nhà phát triển

5
@developerbmw Lưu ý từ hay . Ông trình bày hai phương pháp khác nhau để đạt được mục tiêu.
Ken Wayne VanderLinde

7
Mặc dù cách tiếp cận đơn giản, tốt đẹp, câu trả lời được chấp nhận không trả lời câu hỏi: nhận thư mục con từ thư mục mẹ (còn gọi là anh chị em của thư mục làm việc hiện tại). Để làm như vậy, nó cần thay đổi thư mục làm việc sang thư mục cha.
ryanm

156

Đây là cách bạn chỉ có thể truy xuất các thư mục với GLOB:

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

2
Điều này cũng bao gồm các thư mục chính.
dùng4951

3
Điều này không bao gồm thư mục chính trong trường hợp của tôi (Windows)
marcovtwout

1
Điều này cũng không bao gồm thư mục chính cho tôi trên mac linux. Có lẽ nó phải làm với đường dẫn được sử dụng?
Jake

1
Điều này bao gồm cả đường dẫn $somePathtrong đầu ra
Bố già

47

Lớp Spl DirectoryIterator cung cấp một giao diện đơn giản để xem nội dung của các thư mục hệ thống tập tin.

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

27

Gần giống như trong câu hỏi trước của bạn :

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

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

Thay thế strtoupperbằng chức năng mong muốn của bạn.


1
cảm ơn rất nhiều thêm một câu hỏi: làm thế nào tôi chỉ có thể tách tên thư mục con khỏi toàn bộ đường dẫn?
Adrian M.

@Adrian Xin hãy xem tài liệu API mà tôi đã đưa ra trong câu hỏi khác của bạn. getFilename()sẽ chỉ trả lại tên thư mục.
Gordon

1
Để loại bỏ các dấu chấm, tôi đã phải thêm RecursiveDirectoryIterator::SKIP_DOTSlàm đối số thứ hai cho hàm RecursiveDirectoryIteratortạo.
colan

5

Hãy thử mã này:

<?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;

4

Trong mảng:

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;
}

//truy cập:

$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

Ví dụ để hiển thị tất cả:

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

Bạn có thể thử chức năng này (yêu cầu 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

Cách thích hợp

/**
 * 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);
    });
}

Lấy cảm hứng từ Laravel


1
Điều này có vẻ quá mức khi có một lá cờ GLOB_ONLYDIR, xem php.net/manual/en/feft.glob.php
Robert Pounder

0

Đây là một mã lót:

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

0

Danh sách không đệ quy

Câu hỏi duy nhất hỏi trực tiếp điều này đã bị đóng một cách sai lầm, vì vậy tôi phải đặt nó ở đây.

Nó cũng cung cấp khả năng lọc các thư mục.

/**
 * 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

Tìm tất cả các tệp PHP đệ quy. Logic phải đủ đơn giản để điều chỉnh và nó nhằm mục đích nhanh (er) bằng cách tránh các lệnh gọi hàm.

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;
}

Câu hỏi không yêu cầu danh sách các tập tin, hoặc bất kỳ đệ quy nào. Chỉ cần một danh sách các thư mục trong một thư mục nhất định.
miken32

Tôi nhận thức rõ. Vào thời điểm đó, tôi tin rằng đây là câu trả lời hàng đầu trên Google hoặc tương tự, vì vậy tôi đã thêm giải pháp của mình cho những người đang tìm kiếm một triển khai đệ quy không thổi vào ngăn xếp. Tôi không thấy bất kỳ tác hại nào trong việc cung cấp một cái gì đó có thể được cắt giảm để giải quyết vấn đề ban đầu.
SilbinaryWolf

-1

Nếu bạn đang tìm kiếm một giải pháp liệt kê thư mục đệ quy. Sử dụng mã dưới đây tôi hy vọng nó sẽ giúp bạn.

<?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>'

?>

-1

Hàm đệ quy sau đây trả về một mảng với danh sách đầy đủ các thư mục con

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;
}

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


Câu hỏi không yêu cầu đệ quy. Chỉ là một danh sách các thư mục trong một thư mục nhất định, được cung cấp cho họ vào năm 2010
miken32

-2

Tìm tất cả các tập tin và thư mục trong một thư mục được chỉ định.

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/'));

Mẫu vật :

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)

Đây không phải là một câu trả lời hoàn chỉnh, vì nó không thể chạy được.
miken32

@ miken32 Đó là một câu trả lời hoàn chỉnh, thử lại
A-312
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.