2009-03-03 34 views
29

Tôi đang sử dụng mảnh mã này:Sử dụng scandir() để tìm thư mục trong một thư mục (PHP)

$target = 'extracted/' . $name[0]; 
$scan = scandir($target); 

Để quét các thư mục của một thư mục được sử dụng cho những lần tải zip. Tôi muốn có thể tìm thấy tất cả các thư mục bên trong thư mục $target của mình để tôi có thể xóa chúng và nội dung của chúng, chỉ để lại các tệp trong thư mục $target.

Khi tôi đã trả lại nội dung của thư mục, tôi không biết cách phân biệt giữa các thư mục và tệp để có thể xóa các thư mục.

Ngoài ra, tôi đã được thông báo rằng chức năng rmdir() không thể xóa các thư mục có nội dung bên trong chúng, có cách nào xung quanh vấn đề này không?

Cảm ơn, Ben.

Trả lời

3

Trước hết, rmdir() không thể xóa thư mục có nội dung. Nếu chế độ an toàn bị tắt, bạn có thể sử dụng các mục sau.

exec("rm -rf folder/"); 

Xem thêm is_dir()/is_file() hoặc thậm chí tốt hơn là PHP SPL.

+0

hàm remove bạn làm việc một điều trị! những gì hiện rm-rf thực sự làm gì? Cảm ơn –

+0

Đối với bất cứ ai tự hỏi, 'rm -rf' chạy hàm' rm' trên thư mục đích (thư mục/trong trường hợp này) với các tùy chọn '-r' (đệ quy - đệ quy xóa các tệp và thư mục bên trong thư mục đích) và' -f' (lực - không nhắc với lỗi vv và bỏ qua các tệp không tồn tại). Về cơ bản, nó đảm bảo rằng tất cả các tệp và thư mục bên trong thư mục đích của bạn được xử lý khi loại bỏ mục tiêu. Nói chung nếu bạn thử 'rm' trên một thư mục chứa các nội dung khác, nó sẽ chỉ ném một lỗi nói rằng nó không rỗng. [chi tiết tại đây] (http://www.tutorialspoint.com/unix_commands/rm.htm) – andyface

55

Để xác định có hay không bạn có một thư mục hoặc tập tin sử dụng các chức năng is_dir()is_file()

Ví dụ:

 
$path = 'extracted/' . $name[0]; 
$results = scandir($path); 

foreach ($results as $result) { 
    if ($result === '.' or $result === '..') continue; 

    if (is_dir($path . '/' . $result)) { 
     //code to use if directory 
    } 
} 
+2

Điều này thật tuyệt vời, hoạt động hoàn hảo! Không chắc chắn tôi không hiểu những gì phần này không 'nếu ($ kết quả ==='. 'Hoặc $ kết quả ===' .. ') tiếp tục;', bạn sẽ nhớ giải thích xin vui lòng. Cảm ơn một lần nữa. –

+3

@Ben McRae: Điều này là do scandir trả về kết quả "." và ".." như một phần của mảng, và trong hầu hết các trường hợp, bạn muốn bỏ qua các kết quả đó, đó là lý do tại sao tôi đưa nó vào như một phần của foreach –

+0

Chỉ cần thêm một số thông tin bổ sung: "." đại diện cho thư mục hiện tại, trong khi ".." đại diện cho thư mục mẹ của thư mục. –

2
$directories = scandir('images'); 
foreach($directories as $directory){ 
    if($directory=='.' or $directory=='..'){ 
     echo 'dot'; 
    }else{ 
      if(is_dir($directory)){ 
        echo $directory .'<br />'; 
      } 
    } 
} 

một phiên bản đơn giản hơn và có lẽ nhanh hơn

+0

bạn không lọc liệu kết quả khác có phải là thư mục hay không, hãy để tôi chỉnh sửa và cập nhật nó –

36

Thà sử dụng DirectoryIterator

$path = 'extracted'; // '.' for current 
foreach (new DirectoryIterator($path) as $file) { 
    if ($file->isDot()) continue; 

    if ($file->isDir()) { 
     print $file->getFilename() . '<br />'; 
    } 
} 
1

scandir sẽ quét toàn bộ thư mục, bạn có thể lọc theo cách thủ công.

nhưng nếu bạn là lười biếng như tôi, sau đó sử dụng glob

$scan = glob($target."/*",GLOB_ONLYDIR); 

và nó sẽ ra một mảng của tất cả các thư mục của bạn trong mục tiêu của bạn.

+0

Nó thực sự hiệu quả. Tôi thích nó. và cũng sử dụng nó. Cảm ơn –

0

Bạn cũng muốn xóa các mục nếu chúng nằm trong thư mục đó. rmdir không cho phép bạn xóa các thư mục chứa các tệp. Nhưng có một sollution đơn giản.

array_map('unlink', glob($target.'/*/*')); 
array_map('rmdir',glob($target."/*",GLOB_ONLYDIR)); 

Trước tiên, nó sẽ hủy liên kết tất cả các tệp trong tất cả các thư mục con.
Thứ hai, nó sẽ xóa tất cả các thư mục, vì chúng không chứa tệp.

Nếu bạn đã sub-sub-thư mục, sau đó bạn nên bổ sung thêm 2 dòng như thế này:

array_map('unlink', glob($target.'/*/*/*')); //remove sub-sub-files 
array_map('rmdir',glob($target."/*/*",GLOB_ONLYDIR)); //remove sub-sub-directories 

array_map('unlink', glob($target.'/*/*')); //remove sub-files 
array_map('rmdir',glob($target."/*",GLOB_ONLYDIR)); //remove sub-directories 
0

Cách nhanh chóng và dơ bẩn:

$folders = glob("<path>/*", GLOB_ONLYDIR); 

Một linh hoạt hơn và hướng đối tượng giải pháp, lấy cảm hứng từ câu trả lời sớm hơn bằng cách sử dụng DirectoryIterator nhưng mục đích ngắn gọn hơn và chung hơn:

$path = '<path>'; 
    $folders = []; 

    foreach (new \DirectoryIterator($path) as $file) 
    { 
     if (!$file->isDot() && $file->isDir()) 
     { 
      $folders[] = $file; 
     } 
    } 
0

Để có được tất cả các tập tin trong tất cả các tiểu, tiểu thư mục

function myfunction($dir){ 

foreach ($dir as $dirname => $file) { 

if(is_dir($file) && $file != '.' && $file != '..') { 

    // echo $file; 
     $newDir = scandir($file); 
     myfunction($newDir); 

    }elseif($file !='.' && $file != '..'){ 

     echo "<br>File name is ---"; 
     echo $file; 
    } 

} // end foreach 


} //function ends 

$dirpass = scandir($mypath3); // set directory 
echo myfunction($dirpass); //  pass directory 

Chúng tôi sẽ nhận được kết quả như dưới đây (plz bỏ qua tên tập tin)

File name is ----->index.PHP 
File name is -----> 100000045 Invoices Sales Magento Admin.png 
File name is -----> 100000142 Orders Sales Magento Admin(1).png 
File name is -----> 100000142 Orders Sales Magento Admin.png 
File name is ----->hrc-siberian-tiger-2-jpg_21253111.jpg 
File name is ----->images (3rd copy).jpeg 
File name is ----->images (4th copy).jpeg 
File name is ----->images (5th copy).jpeg 
File name is ----->images (another copy).jpeg 
File name is ----->images (copy).jpeg 
File name is ----->images.jpeg 
File name is ----->JPEG_example_JPG_RIP_100.jpg 
File name is ----->preload 
File name is ----->Stonehenge (3rd copy).jpg 
File name is ----->Stonehenge (4th copy).jpg 
File name is ----->Stonehenge (5th copy).jpg 
File name is ----->Stonehenge (another copy).jpg 
File name is ----->Stonehenge (copy).jpg 
File name is ----->Stonehenge.jpg 
Các vấn đề liên quan