W jaki sposób listować zawartość katalogów w PHP?
Treść dodana: 08 grudnia 2015.
Częstym problemem w pracy z plikami jest konieczność listowania zawartości katalogów oraz plików w nich występujących. Wraz z wprowadzeniem do PHP biblioteki SPL znacząco skrócił się czas potrzebny na utworzenie kodu. Wiele czynności może być zautomatyzowanych, nie wymaga zbytniego wysiłku ze strony programisty. Do pracy z plikami bardzo przydatne stają się klasy SplFileInfo, DirectoryIterator, RecursiveDirectoryIterator. Niestety początkujący programiści nie do końca rozumieją ideę klas, dziedziczenia dlatego z bibliotek tych rzadko korzystają. Być może kilka przykładów rozjaśni temat.
Listowanie zawartości bieżącego katalogu
<?php // ustawienie kontroli błędów // pominę ten blok w kolejnych przykładach error_reporting(E_ALL); ini_set('display_errors', 'on'); ini_set('display_startup_errors', 'on'); try { $directoryIterator = new DirectoryIterator(__DIR__); foreach ($directoryIterator as $dir) { echo '|- ' . $dir->getFilename() . '<br>'; } } catch (Exception $e) { echo $e->getMessage(); }
Kod taki spowoduje wyświetlenie wszystkich plików i katalogów z bieżącego folderu (stała magiczna DIR). Dodatkowo przechwycone zostaną wszystkie wyjątki a ich zawartość wyświetlona na ekranie. Wynikiem naszego kodu stanie się przykładowo:
|- directory.php // nasz plik uruchomieniowy |- Test // przykładowy katalog |- .ukryty // plik ukryty w systemie uniksowym (nazwa zaczyna się od kropki) |- . // bieżący katalog |- .. // katalog wyżej w hierarchii
Nie do końca interesuje nas informacja o katalogu bieżącym i jednym wyżej. Możemy je usunąć metodą isDot():
try { $directoryIterator = new DirectoryIterator(__DIR__); foreach ($directoryIterator as $dir) { if (!$dir->isDot()) { echo '|- ' . $dir->getFilename() . '<br>'; } } } catch (Exception $e) { echo $e->getMessage(); }
Już lepiej, zostały tylko pliki i katalogi główne.
|- directory.php |- Test |- .ukryty
Od wersji PHP 5.3 istnieje także FilesystemIterator rozszerzający DirectoryIterator. Dodano do niego kilka masek oraz stałych. Różnią się też sposobem zwracania danych dla każdej iteracji – FilesystemIterator tworzy nową instancję SplFileInfo podczas gdy DirectoryIterator przesuwa wewnętrzny wskaźnik o 1 (kluczem jest indeks numeryczny).
try { // domyślne flagi, zgodnie z dokumentacją to: // int $flags = FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO | // FilesystemIterator::SKIP_DOTS ] $filesystemIterator = new FilesystemIterator(__DIR__); foreach ($filesystemIterator as $key => $dir) { echo '|- ' . $dir->getFilename() .' - klucz:'. $key. '<br>'; } } catch (Exception $e) { echo $e->getMessage(); }
|- directory.php - klucz: [ścieżka]/directory.php |- Test - klucz: [ścieżka]/Test |- .ukryty - klucz: [ścieżka]/.ukryty
Z racji tego iż domyślnie ustawiona jest flaga FilesystemIterator::SKIP_DOTS katalogi wirtualne (. oraz ..) są automatycznie usuwane.
Listowanie zawartości katalogu i podkatalogów
Rzeczą naturalną jest że katalogi zawierają podkatalogi z dowolną liczbą plików (ograniczoną przez możliwości naszego systemu). Aby je wylistować potrzebny nam będzie RecursiveDirectoryIterator (od wersji PHP 5.3 rozszerza FilesystemIterator):
try { $rdi = new RecursiveDirectoryIterator(__DIR__, RecursiveDirectoryIterator::SKIP_DOTS); $rii = new RecursiveIteratorIterator($rdi, RecursiveIteratorIterator::SELF_FIRST); foreach ($rii as $dir) { echo '|- ' . str_pad($dir->getFilename(), $rii->getDepth() + strlen($dir->getFilename()), '*', STR_PAD_LEFT) . '<br>'; } } catch (Exception $e) { echo $e->getMessage(); }
|- directory.php |- Test |- *data |- **1.php |- *sub |- **5.php |- **4.php |- *1.php |- *2.php |- *3.php |- .ukryty
Należy pamiętać że listowanie dużej liczby plików może znacząco zająć czas maszyny.
Wypisanie drzewa katalogów
Dzięki wbudowanej klasie RecursiveTreeIterator w łatwy sposób możemy wylistować drzewo katalogowe:
try { $rdi = new RecursiveDirectoryIterator(__DIR__, RecursiveDirectoryIterator::SKIP_DOTS); $rii = new RecursiveTreeIterator($rdi, RecursiveIteratorIterator::SELF_FIRST); foreach ($rii as $dir) { echo $dir . '<br>'; } } catch (Exception $e) { echo $e->getMessage(); }
|-[ścieżka]/directory.php |-[ścieżka]/Test | |-[ścieżka]/Test/data | | \-[ścieżka]/Test/data/1.php | |-[ścieżka]/Test/sub | | |-[ścieżka]/Test/sub/5.php | | \-[ścieżka]/Test/sub/4.php | |-[ścieżka]/Test/1.php | |-[ścieżka]/Test/2.php | \-[ścieżka]/Test/3.php \-[ścieżka]/.ukryty
Dodaj komentarz
- php
- composer
- sieć
- http
- apache
- sql server
- javascript
- jquery
- html
- css
- sql
- mysql
- postresql
- mongodb
- pdo
- ajax
- spl
- ssl
- psr
- programowanie
- regex
Wyszukaj interesujące Cię słowa kluczowe pośród istniejących porad.
Komentarze
Nie ma jeszcze żadnych komentarzy do wyświetlenia. Może chcesz zostać pierwszą osobą która podzieli się swoją opinią?