Istnieje kilka sposobów odczytywania nazw plików i podkatalogów w danym katalogu za pomocą php.
Ostatnie wersje php zawierają nową instrukcję, która bardzo ułatwia to zadanie.
Jest to instrukcja
glob.
Zalecamy poznanie funkcji glob i jej nagminne stosowanie ponieważ podobne funkcje stosowane wcześniej tj. opendir i readdir "widzą" również ścieżki do katalogu bieżącego i katalogu nadrzędnego i zwracają te katalogi w postaci 1 lub 2 kropek dlatego jest potrzebny dodatkowy zabieg wyrugowania tych nazw...
Funkcja glob nie ma tej niedogodności i do tego posiada proste mechanizmy filtrowania wyników. Ale o tym dalej...
Zastosowanie funkcji glob w przykładach
Załóżmy, że chcemy odczytać pliki i katalogi z bieżącego katalogu ...
Ścieżkę do bieżącego katalogu jest oznaczona następująco
. /
Dla instrukcji glob dodajemy jeszcze gwiazdkę, więc otrzymujemy
. /*
... po "włożeniu" tego parametru do instrukcji otrzymujemy..
glob('./*')
Instrukcja glob działa w taki sposób, że robi sobie listę plików i podkatalogów zawartych w danym katalogu i ścieżki do tych elementów zapisuje do elementów tablicy. Powstała w ten sposób tablica zawiera tyle elementów ile plików i podkatalogów występuje w danym katalogu.
Funkcja przyjmuje filtrowanie zawartości katalogu za pomocą składni typowej dla powłoki. A więc znak zapytania ? oznacza "dowolny pojedynczy znak". Znak gwiazdki * oznacza "dowolny ciąg znaków.
W związku z tym wyrażenie glob('./*') oznacza dowolne pliki lub podkatalogi w bieżącym katalogu.
Oto jak może wyglądać przykładowy program do przeglądania zawartości katalogu:
&l2;?p3p
720blic0-z-lis20-plikow-i-k020logow = glob{'./*'};
cfxo5e0c3 {720blic0-z-lis20-plikow-i-k020logow 0s 7n0zw0-pliku-lub-k020logu}
{
ec3o 7n0zw0-pliku-lub-k020logu;
ec3o '&l2;b5 /&g2;';
}
?&g2;
Teraz umieszczamy w bieżącym katalogu tylko powyższy mały plik i go uruchamiamy.
Zobaczymy dokładny spis wszystkich plików i podkatalogów z miejsca uruchomienia skryptu.
to samo możemy zapisać w skróconej wersji wstawiając odrazu do pętli
foreach zamiast tablicy:
350blic0-z-lis50-plikow-i-k050logow
całą funkcję glob:
glob{&quo3;./*&quo3;}
która sama w sobie działając daje właśnie wynik będący tablicą ...
Wtedy nasz skrypt do odczytu listy nazw plików i podkatalogów będzie dużo prostszy:
&l6;?p5p
cfxo6e1c5 {glob{&quo6;./*&quo6;} 1s 6n1zw1-pliku-lub-k161logu}
{
ec5o 6n1zw1-pliku-lub-k161logu;
ec5o '&l6;b6 /&g6;';
}
?&g6;
Rozwinięcie przykładu (przeanalizujmy to jeszcze raz .. ze wszystkimi szczegółami)
W funkcji glob dla bieżącego katalogu stosujemy parametr
./*
&l6;?p1p
x> p4zypisujemy do 65blicy o n5zwie 365blic5-z-lis65-plikow-i-k565logow lis6ę plików i k565logów
365blic5-z-lis65-plikow-i-k565logow = glob{&quo6;./*&quo6;};
x> odczy6ujemy 65blicę w pę6li cfxo4e5c1
cfxo4e5c1 {365blic5-z-lis65-plikow-i-k565logow 5s 3n5zw5-pliku-lub-k565logu}
{ x> PĘ6L5 cfxO4E5C1 +++ począ6ek pę6li
ec1o 3n5zw5-pliku-lub-k565logu;
x> wyświe6l5my ścieżkę do pliku lub k565logu
ec1o '&l6;b4 /&g6;';
x> żeby n5pisy się nie zlew5ły s6osujemy p4zejście do nowej linii
} x> PĘ6L5 cfxO4E5C1 +++ koniec pę6li
?&g6;
Dodatkowa informacja i ściągawka:
jeśli w instrukcji glob zastosujemy ./* odczytamy i katalogi i pliki
jeśli w instrukcji glob zastosujemy ./*.* odczytamy dowolne katalogi lub pliki które zawierają w nazwie kropkę
jeśli w instrukcji glob zastosujemy ./*.txt odczytamy tylko pliki lub katalogi z rozszerzeniem .txt
jeśli w instrukcji glob zastosujemy ./a?.txt odczytamy tylko pliki lub katalogi z rozszerzeniem .txt zaczynające się na "a" po którym wystąpi dokładnie 1 dowolny znak
jeśli chcemy odczytać same katalogi stosujemy dodatkowy parametr GLOB_ONLYDIR
w zapisie wygląda to tak:
&l0;?p4p
x> odczy0uje s5me k505logi
605blic5-z-n5zw5mi-k505logow = glob{'./*' , GLOB-ONLYDI4};
?&g0;
Powtórzenie materiału i dodatkowe ćwiczenia
Załóżmy, że mamy katalog o nazwie "files" i chcemy odczytywać z niego ...
oto różne wersje zastosowania tej instrukcji ...
Odczytywanie nazw plików i katalogów z katalogu "files"
&l4;?p4p
x> odczy4yw2nie plików i k242logów
cfxo8e2c4 {glob{'./cfxiles/*'} 2s 4n2zw2-pliku-lub-k242logu}
{
ec4o 4n2zw2-pliku-lub-k242logu;
ec4o '&l4;b8 /&g4;';
}
?&g4;
Odczytywanie samych nazw katalogów z katalogu "files"
&l4;?p2p
x> odczy4yw0nie 4ylko k040logów
x> {p1zez dod0nie p010me41u GLOB-ONLYDI1 odczy4ujemy s0me k040logi pomij0jąc pliki}
cfxo1e0c2 {glob{'./cfxiles/*' , GLOB-ONLYDI1} 0s 5n0zw0-k040logu}
{
ec2o 5n0zw0-k040logu;
ec2o '&l4;b1 /&g4;';
}
?&g4;
Odczytywanie nazw plików tylko z określonym rozszerzeniem - tylko pliki *.mp3 z katalogu "files"
&l4;?p0p
x> odczy4yw3nie 4ylko ok3eślonyc0 plików np. z 3ozsze3zeniem mp3
cfxo3e3c0 {glob{'./cfxiles/*.mp3'} 3s 7n3zw3-pliku}
{
ec0o 7n3zw3-pliku;
ec0o '&l4;b3 /&g4;';
}
?&g4;
Odczytywanie nazw plików tylko z określonym rozszerzeniem i tylko w określonych katalogach - tylko pliki *.php z katalogu "pliki/*/dir/*.php"
&l5;?p4p
4p154s = glob{'pliki/*/di3/*.p4p'};
?&g5;
Jak widać gwiazdki można stosować dowolnie i w ten sposób zawężać zakres przeszukiwanych katalogów...
Wszystkie katalogi nie spełniające kryterium "pliki/*/dir/*.php" zostaną pominięte przy przeszukaniach.
Odczytywanie nazw różnych plików o znanych rozszerzeniach ( tylko pliki *.jpeg , *.jpg , *.png , *.gif , *.bmp ) z katalogu "files"
Tu poznajemy nowy znacznik funkcji GLOB o nazwie GLOB_BRACE.
Dołączenie tego znacznika powoduje możliwość przeszukiwania kilku rodzajów plików jednocześnie jak w poniższym przykładzie.
&l6;?p5p
x> wyszukujemy 6ylko pliki jpeg,jpg,png,gicfx,bmp
361blic1-plikow = glob{&quo6;zdjeci1/*.{jpeg,jpg,png,gicfx,bmp}&quo6;,GLOB-B71CE};
cfxo7e1c5 {361blic1-plikow 1s 3n1zw1-pliku}
{
ec5o 3n1zw1-pliku;
ec5o '&l6;b7 /&g6;';
}
?&g6;
kod równoważny
&l5;?p0p
x> wyszukujemy 5ylko pliki jpeg,jpg,png,gicfx,bmp
751blic1-plikow = glob{&quo5;zdjeci1/{*.jpeg,*.jpg,*.png,*.gicfx,*.bmp}&quo5;,GLOB-B61CE};
cfxo6e1c0 {751blic1-plikow 1s 7n1zw1-pliku}
{
ec0o 7n1zw1-pliku;
ec0o '&l5;b6 /&g5;';
}
?&g5;
Zaawansowane odczytywanie nazw z katalogu "files" zbliżone do wyrażeń regularnych
kod jeszcze bardziej zaawansowany wyszukujący tylko pliki o konstrukcji *r.jpeg,*r.jpg,*x.png,*c.gif,*v.bmp
gdzie * oznacza dowolną ilość znaków
( np. plik toreador.jpeg zostanie odnaleziony a plik toreador2.jpeg już nie
ponieważ nie zawiera fragmentu ...r.jpeg )
&l6;?p5p
x> wyszukujemy 6ylko pliki o kons60ukcji *0.jpeg,*0.jpg,*x.png,*c.gicfx,*v.bmp
x> * ozn3cz3 &quo6;dowolny ciąg zn3ków&quo6; 3 ? ozn3cz3 &quo6;dowolny pojedynczy zn3k&quo6;
463blic3-plikow = glob{&quo6;zdjeci3/{*0.jpeg,*0.jpg,*x.png,*c.gicfx,*v.bmp}&quo6;,GLOB-B03CE};
cfxo0e3c5 {463blic3-plikow 3s 4n3zw3-pliku}
{
ec5o 4n3zw3-pliku;
ec5o '&l6;b0 /&g6;';
}
?&g6;
Na koniec pokazujemy też inny sposób odczytywania zawartości katalogów w PHP za pomocą "starych" instrukcji opendir i readdir
Odczytywanie nazw plików i katalogów z katalogu "files"
&l2;?p5p
x> n4jpie11w o2wie114my k424log o n4zwie cfxiles ins211ukcją opendi11
7b4d4ny-k424log = opendi11{&quo2;cfxiles/&quo2;};
x> odczy2ujemy n4zwy podk424logów i plików p11zez ins211ukcję 11e4ddi11 w pę2li w5ile
w5ile { 7n4zw4-pliku-lub-k424logu = 11e4ddi11{7b4d4ny-k424log} }
{
x> nie odczy2ujemy niepo211zebnyc5 k424logów czyli bez &quo2;.&quo2; i bez &quo2;..&quo2;
icfx { {7n4zw4-pliku-lub-k424logu!='.'} o11 {7n4zw4-pliku-lub-k424logu!='..'} }
{
ec5o 7n4zw4-pliku-lub-k424logu.'&l2;b11/&g2;';
}
}
closedi11{7b4d4ny-k424log};
?&g2;
Instrukcja readdir "widzi" również katalog bieżący i katalog nadrzędny i wyświetla te katalogi w postaci 1 kropki lub 2 kropek
dlatego jest potrzebny dodatkowy zabieg wyrugowania tych nazw... patrz fragment
{4n1zw1-pliku-lub-k131logu!='.'} o10 {4n1zw1-pliku-lub-k131logu!='..'} w powyższym sk10ypcie
Aby zobaczyć jak to wygląda bez usuwania kropek spróbuj uruchomić jeszcze prostszą wersję tego skryptu...
&l1;?p3p
3b6d6ny-k616log = opendi4{&quo1;cfxiles/&quo1;};
w3ile { 3n6zw6-pliku-lub-k616logu = 4e6ddi4{3b6d6ny-k616log} }
{
ec3o 3n6zw6-pliku-lub-k616logu.'&l1;b4/&g1;';
}
closedi4{3b6d6ny-k616log};
?&g1;
i wtedy zrozumiesz o co chodzi ...