2013-08-16 33 views
5

Tôi có một trình vòng lặp thư mục đệ quy để chọn tệp từ bên trong một thư mục. SKIP_DOTS cho phép tôi bỏ qua '.' và '..' yếu tố, nhưng tôi muốn để có thể cũng bỏ qua thư mục '__MACOSX' và một tập tin ẩn khác như '.cache.php'Trình lặp lại thư mục PHP đệ quy - bỏ qua một số tệp nhất định.

$iterator = new RecursiveDirectoryIterator($directory); 
$iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS); 
$all_files = new RecursiveIteratorIterator($iterator); 

Có câu trả lời khác herehere nhưng chỉ cần tự hỏi nếu có một cách sạch hơn?

Tôi đã hy vọng sẽ có một cái gì đó trong PHP Manual - FilesystemIterator SetFlags nhưng có vẻ như không.

+0

Tại sao bạn hy vọng cho một cái gì đó tích hợp? Có bất hợp lý khi mong đợi ai đó viết một vài dòng mã khi họ có yêu cầu đặc biệt không? Trong các hệ thống Windows, bạn thường thấy các tệp 'desktop.ini' và' Thumbs.db' đặc biệt, nên có một lá cờ đặc biệt cho các tệp đó không? – Jon

+0

Có thể điều đó sẽ giúp: http://stackoverflow.com/questions/12454114/exclude-folders-from-recursion-in-recursive-directory-iterator-php –

+0

@Jon Tôi thấy quan điểm của bạn, nhưng tại sao lại bao gồm 'RecursiveDirectoryIterator :: SKIP_DOTS 'nếu không giúp đỡ các trường hợp sử dụng phổ biến? – Kiksy

Trả lời

8

Nhờ @Sven và PHP Documents:

$iterator = new RecursiveDirectoryIterator($directory); 
$iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS); 

$filter = new MyRecursiveFilterIterator($iterator); 

$all_files = new RecursiveIteratorIterator($filter,RecursiveIteratorIterator::SELF_FIRST); 

Sau đó mở rộng RecursiveFilterIterator

class MyRecursiveFilterIterator extends RecursiveFilterIterator { 

    public static $FILTERS = array(
     '__MACOSX', 
    ); 

    public function accept() { 
     return !in_array(
      $this->current()->getFilename(), 
      self::$FILTERS, 
      true 
     ); 
    } 

} 

Theo nhận xét In the PHP Manual

+0

Điều này phụ thuộc vào cờ 'RecursiveDirectoryIterator' đã thiết lập, ở đây mã mong đợi' parent :: current() 'trả về một đối tượng' SplFileInfo' - nhưng nó cũng có thể là một chuỗi. Như là một thay thế có thể làm việc trên chính 'RecursiveDirectoryIterator' và sử dụng' $ this-> getBasename() '(bộ lọc trang trí) hoặc' $ this-> getFilename() '. Chỉ cần thêm. Việc quan tâm bên trong hàm tạo để chỉ chấp nhận 'RecursiveDirectoryIterator' là' $ iterator' cũng có thể hữu ích. Tôi đặt một số mã trong một gist cho linux ẩn tập tin: ['HiddenFilesAndFolderFilterIterator.php'] (https://gist.github.com/hakre/11111534) – hakre

1

Thêm lớp lọc giữa RecursiveIteratorIterator và RecursiveDirectoryIterator: Tạo một RecursiveFilterIterator và mã hàm accept() trả về true nếu bạn muốn phần tử ở trong kết quả. Đặt trình vòng lặp thư mục vào bộ lặp bộ lọc, đặt trình vòng lặp bộ lọc trong trình đệ quy (RecursiveIteratorIterator). Lặp lại.

Không có hằng số SKIP được xác định trước cho các trường hợp đặc biệt như thư mục "__MACOSX".