Názvy súborov v priečinku php. Získanie zoznamu súborov a adresárov pomocou PHP. Výpis jedného adresára

  • 03.11.2019

Práca so súbormi

Potreba súborových operácií vzniká pred programátorom veľmi často. Ak vaše skripty nepoužívajú databázy, potom sú súbory jediným prijateľným úložiskom informácií pre skript. Používanie súborov ako úložiska informácií o vykonávaní skriptov umožňuje ich použitie v širokej škále situácií. Takmer všetky skripty-počítadlá niečoho sú napísané na základe práce so súbormi. Je možné uviesť aj kopu iných príkladov, no je čas prejsť priamo od slov k činom.

Chcem hneď povedať, že práca so súborom musí byť autorizovaná. PHP štandardne neumožňuje manipuláciu so súborom z bezpečnostných dôvodov. Ak chcete odstrániť tento zákaz v správcovi FTP CuteFTP, nastavte všetky začiarkavacie políčka vo vlastnostiach súboru, v iných manažéroch by malo byť niečo podobné.

file_exists

Pred vykonaním akýchkoľvek operácií so súborom je často potrebné uistiť sa, že zadaný súbor vôbec existuje. Toto robí funkcia file_exists. Táto funkcia môže vrátiť iba dve hodnoty, ako si viete predstaviť, PRAVDA(ak zadaný súbor existuje) a FALSE... Použitie tejto funkcie zvyčajne vyzerá takto:

Upozorňujeme, že funkcia funguje iba na lokálnych súboroch, to znamená, že ak chcete skontrolovať, či Yandex získal súbor robot.txt, vaše úsilie bude márne. Ale na druhej strane je možné skontrolovať akýkoľvek súbor na lokálnom serveri bez ohľadu na adresár, v ktorom sa nachádza.

Tu je niekoľko pravidiel na popis cesty k súboru.

veľkosť súboru

Ako už názov napovedá, funkcia určí veľkosť súboru a vráti ju v bajtoch. Je to užitočné, ak chcete v súbore skontrolovať prítomnosť informácií (ako viete, prázdny súbor obsahuje 0 bajtov) a tiež je možné skontrolovať veľkosť súboru, či neprekračuje určitý limit.

súbor

Táto funkcia už funguje priamo so súborom. Vráti obsah zadaného súboru, a to vo forme poľa, kde každý z jeho prvkov je riadok súboru. Funkcia je užitočná, keď potrebujete uložiť niekoľko rôznych hodnôt do jedného súboru, ktoré by sa nemali prekrývať. Potom je každá hodnota uložená na samostatnom riadku a čítaná funkciou súboru, ktorá vracia pole, v dôsledku čoho dôjde k odkazu na zadanú premennú prečítaním hodnoty prvku poľa s indexom zodpovedajúcim riadku v súbor.

Okrem toho je možné znova spojiť všetky prvky vráteného poľa do jednej premennej. To sa vykonáva pomocou funkcie implode array.

fopen

Ak je predchádzajúca funkcia sebestačná a vo všeobecnosti nesúvisí s inými funkciami, potom nasledujúce funkcie na prácu so súbormi fungujú v spojení s fopen. Táto funkcia otvorí zadaný súbor a vráti identifikátor pripojenia súboru, ktorý sa používa na servisné účely. Táto funkcia nie je žiadnym spôsobom spojená s obsahom súboru.

Funkcia fopen má niekoľko režimov práce so súborom. Sú uvedené za názvom súboru a predstavujú nasledujúce označenia:

    "r"
    Súbor sa otvorí len na čítanie jeho obsahu.

    "r +"
    Otvorenie súboru na čítanie aj zápis.

    "w"
    Súbor sa otvorí na účely zápisu.

    "w +"
    Otvorte súbor na čítanie a zápis.

    "a"
    Súbor sa otvorí na zápis na koniec súboru (prepisovanie).

    "a +"
    Otvorí sa na ďalšie písanie a čítanie.

fgets

Funkcia na čítanie súboru otvoreného pomocou fopen. Na rozdiel od súboru však táto funkcia pri každom spustení vráti iba jeden riadok súboru, pričom presunie interný ukazovateľ súboru na ďalší riadok, ktorý prečíta pri ďalšom volaní funkcie. Preto, ak potrebujete prečítať celý súbor, musíte túto funkciu použiť v slučke.

Všimnite si, že fgets má ďalší parameter length, ktorý určuje maximálnu dĺžku riadku súboru na čítanie. Ak veľkosť reťazca presiahne toto číslo, funkcia ho vráti v „skrátenej“ forme dĺžky bajtov. Štandardne je tento parameter nastavený na 1024 bajtov alebo jeden kilobajt. Okrem toho venujte pozornosť tomuto parametru, ak používate veľké súbory, pretože pri čítaní takýchto súborov môže dôjsť k pretečeniu vykonávacej pamäte PHP (jej veľkosť je uvedená v konfiguračnom súbore), čo povedie k zamrznutiu.

Všimnite si, že na označenie súboru, ktorý sa má čítať, musí byť zadaný identifikátor pripojenia súboru vrátený funkciou fopen, a nie názov súboru (v našom príklade je to hodnota premennej $ file).

fputs

Funkcia zapisovania informácií do súboru a robí to podľa princípu funkcie fgets, to znamená, že začína zapisovať z pozície interného ukazovateľa súboru. Vo všeobecnosti je táto funkcia v mnohom podobná vyššie uvedenej: využíva aj parameter dĺžky zaznamenaných údajov, ktorý je tiež voliteľný.

fclose

Ako ste možno uhádli, táto funkcia zatvorí zadaný súbor. V skutočnosti, keď skript dokončí vykonávanie, PHP sám zatvorí všetky súbory, ktoré otvorí, ale stále je lepšie to urobiť ručne. Ako parameter funkcie musíte zadať identifikátor pripojenia súboru.

Na ilustráciu kombinácie vyššie uvedených funkcií uvedieme príklad vytvorenia jednoduchého počítadla zásahov.

$ súbor = fopen ("counter.txt", "r");
$ c = fgets (súbor $, 150);
fclose (súbor $);
$ c ++;
$ súbor = fopen ("counter.txt", "w");
fputs (súbor $, $ c);
fclose (súbor $);
echo $ c;
?>

Práca s adresármi

S operáciami so súbormi úzko súvisia operácie s adresármi. Algoritmus na prácu s nimi je podobný operáciám so súbormi: najprv musíte otvoriť adresár, vykonať nejaké akcie a nakoniec ho zavrieť.

opendir

Táto funkcia otvorí zadaný adresár a vráti identifikátor služby pripojenia adresára. Cesty k adresárom by mali byť špecifikované takto:

Bodka znamená otvorenie aktuálneho adresára

. / súbory /

Otvorenie priečinka súbory nachádza v aktuálnom adresári

Otvorenie priečinka o úroveň vyššie ako je aktuálna

readdir

Funkcia načíta adresár otvorený opendir. Pri každom prechode vráti názov súboru alebo priečinka v zadanom adresári a presunie interný ukazovateľ na ďalší objekt v adresári. Takže na prečítanie celého adresára sa musí použiť v slučke.

Malo by sa tiež poznamenať, že táto funkcia vracia objekty služby priečinka. . a .. ktoré možno vo výstupe skrátiť príkazom IF.

uzavretý

Zatvorte adresár zadaním identifikátora pripojenia priečinka ako argumentu.

Niekedy používanie adresárových funkcií značne uľahčuje život. Napríklad v časti Funkcie môžete vidieť zoznam funkcií v abecednom poradí. Predstavte si, koľko času by zabralo manuálne napísanie celého tohto zoznamu s odkazmi a dokonca aj v abecednom poradí. A práve tu mi pomohli funkcie práce s adresárom. Každá funkcia bola umiestnená v samostatnom súbore s názvom zodpovedajúcim názvu funkcie, bez akýchkoľvek prípon.

Takže zakaždým, keď navštívite stránku, dostanete novo vygenerovaný zoznam funkcií.

To je všetko. Uvidíme sa v ďalšej lekcii.

V tejto lekcii sa budeme zaoberať typickou úlohou, ktorá vzniká pri práci na projekte PHP: získanie zoznamu súborov a adresárov. Poďme diskutovať o niekoľkých základných a sofistikovanejších prístupoch, pričom uvedieme výhody a nevýhody každého z nich. Prvé tri riešenia budú používať všeobecné funkcie PHP a potom predstavia robustnejšie riešenie pomocou iterátorov SPL.

Pre vecnú diskusiu o riešení a demonštráciách predpokladajme, že adresárová štruktúra je takáto:

\ --- manažér | \ --- používateľ | \ --- document.txt | \ --- data.dat | \ --- style.css | --- article.txt | --- master.dat | --- script.php | --- test.dat | --- text.txt

Základné riešenia

Prvá sada riešení sa opiera o funkciu glob (), kombináciu funkcií opendir (), readdir () a closedir () a tiež funkciu scandir ().

Použitie glob ()

Prvé riešenie sa spolieha na funkciu glob (), ktorá umožňuje hľadanie cesty pomocou vzorov. Funkcia má dva parametre:

  • $ vzor (povinné): vzor vyhľadávania
  • $ flags (voliteľné): jeden alebo viac príznakov, ktorých popis nájdete v dokumentácii

Pozrime sa na niekoľko príkladov. Ak chcete v adresári vyhľadať všetky súbory a adresáre, ktorých názvy končia na .TXT, mal by sa použiť kód:

Ak vytlačíme premennú $ filelist, dostaneme:

Pole (0 => "clanok.txt", 1 => "text.txt")

Ak potrebujete zoznam súborov a adresárov, ktorých názvy začínajú na „te“, kód bude vyzerať takto:

A výstup vyzerá takto:

Pole (0 => "test.dat", 1 => "text.txt")

A ak chcete získať zoznam iba adresárov s názvami obsahujúcimi „ma“, použite kód:

Posledný príklad vypíše:

Pole (0 => "správca")

Všimnite si, že posledný príklad používa príznak GLOB_ONLYDIR ako druhý parameter funkcie. Preto bol súbor master.dat vylúčený zo zoznamu. Hoci sa funkcia glob () používa veľmi jednoducho, niekedy nie je dostatočne flexibilná. Napríklad neexistuje žiadny príznak na získanie iba súborov (žiadne adresáre), ktoré zodpovedajú vzoru.

Používame opendir (), readdir () a closedir ().

Druhým prístupom k výpisu súborov a adresárov, o ktorom budeme diskutovať, je použitie funkcií opendir (), readdir () a closedir ().

Opendir () otvorí adresár a vráti handle na pripojenie. Po získaní deskriptora je možné použiť funkciu readdir (). Pri každom volaní táto funkcia udáva názov ďalšieho súboru alebo adresára v otvorenom adresári. Ak už boli uvedené všetky mená, funkcia sa vráti falošné... Funkcia closedir () sa používa na zatvorenie deskriptora.

Na rozdiel od použitia funkcie glob () je tento prístup komplikovanejší, pretože nemáte parametre, ktoré by pomohli filtrovať zoznam vrátených názvov súborov a adresárov. Aby ste dosiahli požadovaný výsledok, musíte vykonať filtrovanie sami.

Nasledujúci príklad vráti zoznam názvov súborov a adresárov začínajúcich na „te“:

Po vykonaní vyššie uvedeného kódu bude vstupná premenná $ obsahovať inklúzie, ako napríklad „.“ a "..". Toto sú dva virtuálne adresáre, ktoré sa nachádzajú v každom adresári v súborovom systéme. Predstavujú aktuálny adresár a nadradený adresár.

Druhý príklad vytlačí iba súbory obsiahnuté v danom adresári.

Príklad poskytne nasledovné:

Pole (0 => "article.txt", 1 => "master.dat", 2 => "script.php", 3 => "test.dat", 4 => "text.txt")

Pomocou scandir ()

Na záver si predstavme funkciu scandir (). Má len jeden povinný parameter: cestu na čítanie. Funkcia vráti pole súborov a adresárov umiestnených na zadanej ceste. Ak chcete získať zoznam súborov a adresárov podľa určitého kritéria, musíte vykonať dodatočné filtrovanie. Na druhej strane je riešenie stručnejšie a nevyžaduje správu deskriptorov.

Tento príklad ukazuje, ako získať zoznam súborov a adresárov, ktorých názvy začínajú na „te“:

Použitie iterátorov SPL

Teraz sa pozrime na používanie iterátorov SPL. Ale skôr, než začneme riešiť náš problém, predstavme si knižnicu SPL a iterátory. SPL poskytuje sériu tried pre objektovo orientované dátové štruktúry, iterátory, deskriptory súborov a ďalšie.

Jednou z výhod iterátorov je, že ide o triedy a možno ich rozšíriť tak, aby vyhovovali vašim vlastným potrebám. Ďalším plusom je, že iterátory majú svoje vlastné metódy, ktoré sú užitočné pri riešení mnohých bežných problémov a sú umiestnené na jednom mieste. Pozrite si príklad použitia FilesystemIterator oproti readdir (). Obidve metódy používajú slučku, ale v prípade readdir () spracovávate iba reťazec, zatiaľ čo FilesystemIterator pracuje s objektom, ktorý môže obsahovať ďalšie informácie o súbore alebo adresári (veľkosť, vlastník, oprávnenia atď.).

PHP samozrejme poskytuje možnosť získať tieto informácie pomocou funkcií ako veľkosť súboru () a vlastník súboru (). Ale PHP5 je založené na použití konceptu OOP. Preto je lepšie využívať moderné metódy práce s programovacím jazykom. Na našej stránke sú návody venované práci s iterátormi.

Ako je uvedené vo vodnej časti tutoriálu, pozrieme sa na používanie FilesystemIterator, RecursiveDirectoryIterator a GlobIterator. Prvý z nich dedí z DirectoryIterator a zvyšok z FilesystemIterator. Všetky majú rovnaký konštruktor, ktorý má dva parametre:

  • $ cesta (povinné): cesta k položke súborového systému, s ktorou sa má pracovať
  • $ flags (voliteľné): jeden alebo viac príznakov uvedených v dokumentácii

Skutočný rozdiel v týchto iterátoroch je v tom, ako sa používajú na navigáciu po danej ceste.

FilesystemIterator

FilesystemIterator sa používa veľmi jednoducho. Pozrime sa na to v praxi. Tu sú dva príklady. Prvý zobrazuje vyhľadávanie všetkých súborov a adresárov, ktorých názvy začínajú na „te“. Druhý príklad používa iný iterátor, RegexIterator, na nájdenie všetkých súborov a adresárov, ktoré končia na „t.dat“ alebo „t.php“. RegexIterator sa používa na filtrovanie výsledku na základe regulárnych výrazov.

getFilename (), "te") === 0) ($ zoznam súborov = $ záznam-> getFilename ();))

Vyššie uvedený kód poskytne výsledok podobný predchádzajúcim príkladom.

Druhý príklad použitia RegexIterator:

getFilename (); )

Výstupom bude:

Pole (0 => "script.php", 1 => "test.dat")

RecursiveDirectoryIterator

RecursiveDirectoryIterator poskytuje rozhranie na rekurzívne prechádzanie adresármi v súborovom systéme. Má niekoľko užitočných metód, ako napríklad getChildren () a hasChildren (), ktoré vracajú iterátor pre aktuálne umiestnenie, ak ide o adresár, a kontrolujú, či je aktuálnym vstupným bodom adresár. Nasledujúci príklad ukazuje použitie RecursiveDirectoryIterator a getChildren (). Výsledok bude rovnaký ako v predchádzajúcich príkladoch.

getChildren (), "/t\.(php|dat)$/"); $ zoznam súborov = pole (); foreach ($ filter ako $ záznam) ($ zoznam súborov = $ záznam-> getFilename ();)

GlobIterator

GlobIterator iteruje cez súborový systém rovnakým spôsobom ako funkcia glob (). Prvý parameter môže obsahovať zástupný znak názvu. Príklad ukazuje použitie GlobIterator s rovnakým výsledkom ako predtým.

getFilename (); )

Záver

Táto lekcia ukazuje použitie rôznych prístupov na dosiahnutie rovnakého cieľa: získanie zoznamu súborov a adresárov. Mali by sa pamätať na tieto kľúčové body:

  • Funkcia glob () je vstavané riešenie, ale nie je dostatočne flexibilné.
  • Riešenie založené na opendir (), readdir () a closedir () je zložitejšie a vyžaduje dodatočné filtrovanie, ale je flexibilnejšie.
  • Funkcia scandir () vyžaduje dodatočné filtrovanie, ale funguje bez spracovania deskriptora.
  • Ak používate prístup OOP, mali by ste použiť knižnicu SPL. Okrem toho môžete triedy rozšíriť o svoje vlastné funkcie.
  • GlobIterator má funkciu predfiltra, zatiaľ čo iné používajú RegexIterator.

Reg.ru: domény a hosting

Najväčší registrátor a poskytovateľ hostingu v Rusku.

V prevádzke je viac ako 2 milióny doménových mien.

Propagácia, mail pre doménu, obchodné riešenia.

Svoj výber si už vybralo viac ako 700 tisíc zákazníkov po celom svete.

* Posunutím myši pozastavíte rolovanie.

Späť dopredu

Získanie zoznamu priečinkov pomocou PHP

Výpis adresárov pomocou PHP alebo výpis adresárov

Výpis adresára budeme nazývať všeobecný dotaz, ktorý tvorí zoznam všetkých alebo niektorých súborov a adresárov nadradeného adresára – proces podobný práci indexovej stránky poskytovanej väčšinou webových serverov, ale s O Väčšia kontrola nad obsahom a jeho formátovaním.

Ďalšou výhodou tohto skriptu je možnosť vykonávať určité akcie so súbormi pomocou PHP. V každom prípade, prvým krokom, ktorý musíme urobiť, je dotaz na súborový systém – vrátiť zoznam súborov a adresárov.

Nižšie uvedené funkcie vám umožňujú získať názvy súborov a ďalšie vlastnosti z konkrétneho adresára alebo rekurzívne prechádzať podkategóriami.

komentár: PHP5 má funkciu scandir, ktorý "vracia zoznam súborov a adresárov v adresári na danej ceste", nezobrazuje však žiadne ďalšie informácie o súboroch v adresári.

Výpis jedného adresára

Na začiatok uvádzame príklad jednoduchej funkcie, ktorá vracia zoznam súborov, adresárov a ich vlastností z jedného adresára (pokročilejšie verzie tejto funkcie nájdete neskôr v tomto návode.)

čítať ())) (// preskočiť skryté súbory, ak (položka $ == ".") pokračovať; ak (is_dir ("položka $ dir $")) ($ retval = pole ("name" => "$ dir $" záznam / "," veľkosť "=> 0," lastmod "=> čas súboru (" $ dir $ záznam "));) elseif (je_čitateľný (" $ dir $ záznam ")) ($ retval = pole (" názov "= > "$ dir $ položka", "veľkosť" => veľkosť súboru ("$ dir $ položka"), "lastmod" => filemtime ("$ dir $ položka"));)) $ d-> zavrieť (); návrat $ retval; )?>

Túto funkciu môžete použiť nasledovne:

Návratová hodnota je asociatívne pole súborov vrátane informácií o ceste k súboru, veľkosti a dátumu poslednej úpravy, pokiaľ súbor nie je adresár, v takom prípade sa namiesto veľkosti súboru zobrazí reťazec „(dir)“.

Príklad 1:

", print_r ($ dirlist),""; / * vzorový výstup Pole (=> Pole (=> obrázky / pozadie0.jpg => obrázok / jpeg => 86920 => 1077461701) => ...) * /?>

Príklad 2:

", print_r ($ dirlist),""; / * vzorový výstup Pole (=> Pole (=> ./images/background0.jpg => obrázok / jpeg => 86920 => 1077461701) => ...) * /?>

Zoznam súborov cez HTML

Aby sme získali výsledky výstupu na stránke v HTML, prejdeme cez vrátené pole cez slučku.

\ n "; echo" názovTypVeľkosťPosledný mod.\ n "; foreach ($ dirlist ako súbor $) (echo" \ n "; echo" ($ súbor ["názov"])\ n "; echo" ($ súbor ["typ"])\ n "; echo" ($ súbor ["veľkosť"])\ n "; echo" \ n "; echo"\ n ";) echo"\ n \ n ";?>

Tento kód sa dá pomerne ľahko upraviť, napríklad:

  • - zobraziť výsledky výpisu ako zoznam namiesto tabuľky;
  • - vytvoriť z názvov súborov aktívne odkazy;
  • - nahradiť názvy ikonami podľa typu súboru;
  • atď.

Ak chcete napríklad vytlačiť iba súbory PNG, pridajte do výstupnej slučky jednoduchú podmienku:

\ n "; echo" názovTypVeľkosťPosledný mod.\ n "; foreach ($ dirlist ako súbor $) (// skontrolujte, či súbor patrí do PNG, ak (! preg_match (" / \. png $ / ", $ súbor [" názov "])) pokračovať; echo" \ n "; echo" ($ súbor ["názov"])\ n "; echo" ($ súbor ["typ"])\ n "; echo" ($ súbor ["veľkosť"])\ n "; echo" ", dátum (" r ", $ súbor [" lastmod "]),"\ n "; echo"\ n ";) echo"\ n \ n ";?>

Tento príklad preskočí a skryje všetky súbory, ktorých názvy končia na .png... Môžete tiež použiť ďalšie podmienky na základe typu súboru, veľkosti alebo dátumu poslednej úpravy.

Ak chcete napríklad zobraziť miniatúru, odkaz na väčší obrázok alebo dokonca video, stačí dať týmto 2 súborom rovnaké názvy a vo vyššie uvedenom skripte použiť str_replace alebo podobná funkcia na úpravu obsahu odkazov.

Rekurzívny výpis adresárov

A keďže sme sa dostali až sem, vo funkcii pre volanie rekurzívneho zoznamu a podkategórií nastanú len drobné zmeny. Pridaním druhého parametra do funkcie zachováme predchádzajúcu funkciu výpisu jedného adresára.

čítať ())) (// preskočiť skryté súbory, ak (položka $ == ".") pokračovať; ak (is_dir ("položka $ dir $")) ($ retval = pole ("name" => "$ dir $" entry / "," size "=> 0," lastmod "=> filemtime (" $ dir $ entry ")); if ($ recurse && is_readable (" $ dir $ entry / ")) ($ retval = array_merge ($ retval, getFileList ("$ dir $ entry /", true));)) elseif (is_readable ("$ dir $ entry")) ($ retval = pole ("name" => "$ dir $ entry", "veľkosť "=> veľkosť súboru (" $ dir $ záznam ")," lastmod "=> filemtime (" $ dir $ záznam "));)) $ d-> zavrieť (); návrat $ retval; )?>

Aby nová funkcia fungovala, musíte zadať hodnotu pravda(alebo 1) ako druhý parameter.

Pred opakovaním skriptu skontrolujte, či sú podadresáre čitateľné, a prečítajte si aj posledný odsek tejto lekcie, aby ste sa vyhli chybám v prístupe.

Ako predtým, návratovou hodnotou je pole, asociatívne polia. V skutočnosti je jediným doplnkom ďalšia dodatočná možnosť rekurzívneho výpisu.

Obmedzenie hĺbky rekurzie

Tento posledný príklad pridáva ďalšiu vlastnosť – schopnosť určiť, ako „hlboko“ má rekurzia ísť. Predchádzajúci kód bude pokračovať v skúmaní podadresárov, kým sa neminie. Tento skript vám pomôže nastaviť limit počtu úrovní vnorených adresárov.

čítať ())) (// preskočiť skryté súbory, ak (položka $ == ".") pokračovať; ak (is_dir ("položka $ dir $")) ($ retval = pole ("name" => "$ dir $" entry / "," size "=> 0," lastmod "=> filemtime (" $ dir $ entry ")); if ($ recurse && is_readable (" $ dir $ entry / ")) (if ($ hĺbka == = false) ($ retval = array_merge ($ retval, getFileList ("$ dir $ položka /", true));) elseif ($ hĺbka> 0) ($ retval = array_merge ($ retval, getFileList ("$ dir $ položka) / ", pravda, $ hĺbka-1));))) elseif (je_čitateľné (" $ dir $ položka ")) ($ retval = pole (" názov "=>" $ dir $ položka "," veľkosť "=> veľkosť súboru ("$ dir $ položka"), "lastmod" => filemtime ("$ dir $ položka"));)) $ d-> zavrieť (); návrat $ retval; )?>

Ako predtým, pridali sme iba 1 nový parameter a pár riadkov kódu. Ak nie je špecifikovaná predvolená hodnota zodpovedná za hĺbku rekurzie, potom je nastavená na falošné... To nám umožňuje mať istotu, že predchádzajúce funkcie zostanú zachované a nasledujúci kód sa pri zmene funkcie „nerozbije“.

Výpis adresárov je získanie informácií o adresároch a súboroch pre daný nadradený adresár, ako aj možnosť použiť na tieto údaje rôzne filtre na opravu výstupu.

V tomto príklade sa pokúsime vyrovnať s typickou úlohou, ktorá sa vyskytuje takmer v každom PHP projekt - získanie zoznamu adresárov a (alebo) súborov. V príklade sa používa trochu základný a sofistikovanejší prístup, v ktorom sú načrtnuté výhody a nevýhody každej techniky. Prvé tri riešenia využívajú všeobecné funkcie PHP. Posledné spoľahlivejšie riešenie využívajúce iterátory PHP SPL.


Pre vizuálnejšiu reprezentáciu používame adresárovú štruktúru, ktorá vyzerá takto:


\ -Aplikácia | \ -Používateľ | \ -data.apk | \ -style.css | \ -test.txt | -readme.txt | -script.php | -serial.txt | -test.html | -test.js

Základné riešenia
Prvá skupina príkladov používa funkcie glob () a kombinácia funkcií opendir (), readdir (), uzavretý () a tiež funkciu scandir ().

Použitie glob ()

Príklad použitia funkcie php glob (), ktorý vám umožňuje vyhľadať vzor cesty.
Funkcia glob ( $ vzor,$ vlajky) funguje na dvoch argumentoch:
  • $ vzor(povinné): reťazec vzoru vyhľadávania
  • $ vlajky
    • GLOB_MARK- Pridá lomku do každého vráteného adresára.
    • GLOB_NOSORT- Vráti súbory tak, ako sú v adresári (bez triedenia). Ak tento príznak nie je zadaný, mená sa zoradia podľa abecedy.
    • GLOB_NOCHECK- Vráti vyhľadávací vzor, ​​ak sa pomocou neho nenašli žiadne súbory.
    • GLOB_NOESCAPE- Spätné lomky neuniknú meta znakom.
    • GLOB_BRACE- Rozšíri (a, b, c), aby sa zhodovalo s "a", "b" alebo "c".
    • GLOB_ONLYDIR- Vráti iba adresáre zodpovedajúce vzoru.
    • GLOB_ERR- Zastaví sa pri chybách čítania (napríklad adresáre bez prístupu na čítanie), chyby sú štandardne ignorované.
Ak chcete v adresári vyhľadať všetky súbory a adresáre, ktorých názvy končia príponou .txt, použite kód:Výstup poskytne nasledujúci výsledok: pole (2) (=> reťazec (10) "readme.txt" => reťazec (10) "serial.txt") Ak potrebujete získať zoznam súborov a adresárov, ktorých názvy začínajú s "te":Vo výstupe dostaneme nasledujúci výsledok: pole (2) (=> reťazec (9) "test.html" => reťazec (7) "test.js") Dostaneme sa do zoznamu iba adresárov s názvami obsahujúcimi "er" :Vo výstupe dostaneme nasledujúci výsledok: pole (1) (=> reťazec (4) "Používateľ")

Posledný príklad používa vlajku GLOB_ONLYDIR ako druhý argument funkcie. Preto bol do zoznamu zahrnutý iba adresár "Používateľ" v názve, ktorý sa nachádza s "er". Funkcia glob () sa používa veľmi jednoducho, no niekedy nie je dostatočne flexibilná. Neexistuje žiadny príznak na načítanie iba súborov (žiadne adresáre), ktoré zodpovedajú vzoru.

Pomocou opendir (), readdir () a closedir ().

Ďalším spôsobom, ako získať zoznam súborov a adresárov, je použitie funkcií PHP opendir (), readdir () a uzavretý ().

Funkcia opendir () vráti popisovač do otvoreného adresára. Po získaní deskriptora môžete funkciu použiť readdir ()... Pri prístupe k deskriptoru funkcia readdir () dáva názov nasledujúceho súboru alebo adresára. Ak už boli uvedené všetky prvky obsiahnuté v deskriptore, funkcia readdir () vráti sa falošné... Na zatvorenie deskriptora použite funkciu uzavretý ().


Na rozdiel od použitia funkcie php , tento prístup je trochu komplikovanejší. Nie je možné nastaviť parametre filtrovania, ktoré pomáhajú vopred vytvoriť zoznam vrátených názvov súborov a adresárov. Ak chcete získať požadovaný zoznam súborov a adresárov, musíte filtrovanie vykonať sami.


Vyššie uvedený príklad vráti zoznam názvov súborov a adresárov začínajúcich na „Us“:Výstup poskytne nasledujúci výsledok: pole (1) (=> reťazec (4) "Používateľ") Nasledujúci príklad zobrazí iba súbory obsiahnuté v zadanom adresári.Vo výstupe dostaneme nasledujúci výsledok: pole (5) (=> reťazec (10) "script.php" => reťazec (7) "test.js" => reťazec (9) "test.html" => reťazec (10) "serial.txt" => reťazec (10) "readme.txt")

Pomocou scandir ().

Na dokončenie si pozrime príklad použitia funkcie php scandir ()... Má len jeden povinný atribút – cestu k adresáru na čítanie. Výsledkom operácie funkcie je pole súborov a adresárov umiestnených na ceste zadanej v argumente. Rovnako ako v predchádzajúcom príklade, ak chcete získať filtrovaný zoznam súborov a adresárov, musíte to urobiť sami. Riešenie je vizuálne kratšie a nevyžaduje správu deskriptorov.


Príklad ukazuje, ako získať zoznam súborov a adresárov, ktorých názvy začínajú na „te“:Vo výstupe dostaneme nasledujúci výsledok: pole (2) (=> reťazec (9) "test.html" => reťazec (7) "test.js")

Pokročilé riešenie využívajúce PHP SPL
Robustnejšie riešenie využívajúce iterátory SPL FilesystemIterator, RecursiveDirectoryIterator a GlobIterator.

Použitie iterátorov SPL.

Zvážte použitie iterátorov SPL. Skôr než začneme problém riešiť, zoznámime sa s php SPL knižnicou a iterátormi. Knižnica SPL poskytuje špecializovanú sadu tried pre objektovo orientované dátové štruktúry, iterátory, deskriptory súborov a ďalšie.


Hlavnou výhodou iterátorov je, že ide o triedy a možno ich rozšíriť pomocou štandardného mechanizmu dedenia tried php. Ďalším plusom je, že iterátory majú svoje vlastné metódy, ktoré môžu byť užitočné pri riešení typických problémov, a všetky sú umiestnené na jednom mieste. Pozrime sa na príklad použitia FilesystemIterator a porovnať s readdir ()... Obe metódy používajú slučku, ale v prípade readdir () spracuje iba reťazec, ale FilesystemIterator vie pracovať s objektom. Môže obsahovať ďalšie informácie o súbore alebo adresári, ako je vlastník, veľkosť, oprávnenia atď.


Samozrejme, PHP má schopnosť získať tieto informácie pomocou funkcií, veľkosť súboru (), vlastník súboru () a ďalšie. Ale PHP, ako každý programovací jazyk, má vlastnosti, ktoré treba zmeniť. V PHP5 rastie túžba používať koncepty OOP. Preto je lepšie využívať moderné metódy práce s programovacím jazykom.


Zvážte použitie FilesystemIterator, RecursiveDirectoryIterator a GlobIterator... Prvý iterátor dedí z DirectoryIterator a zvyšok z FilesystemIterator... Všetky majú rovnaký konštruktor, ktorý má dva argumenty:

  • $ cesta(povinné): cesta k položke súborového systému, na ktorej sa vykonávajú operácie
  • $ vlajky(voliteľné): jeden alebo viac príznakov
    • FilesystemIterator :: CURRENT_AS_PATHNAME Spôsobí, že metóda FilesystemIterator :: current () vráti cestu.
    • FilesystemIterator :: CURRENT_AS_FILEINFO Spôsobí, že metóda FilesystemIterator :: current () vráti inštanciu SplFileInfo.
    • FilesystemIterator :: CURRENT_AS_SELF Spôsobí, že metóda FilesystemIterator :: current () vráti $ this (FilesystemIterator).
    • FilesystemIterator :: CURRENT_MODE_MASK Masky FilesystemIterator :: aktuálne ()
    • FilesystemIterator :: KEY_AS_PATHNAME Spôsobí, že metóda FilesystemIterator :: key () vráti cestu.
    • FilesystemIterator :: KEY_AS_FILENAME Spôsobí, že metóda FilesystemIterator :: key () vráti názov súboru.
    • FilesystemIterator :: FOLLOW_SYMLINKS Spôsobí, že metóda RecursiveDirectoryIterator :: hasChildren () bude nasledovať symbolické odkazy.
    • FilesystemIterator :: KEY_MODE_MASK Masky FilesystemIterator :: kľúč ()
    • FilesystemIterator :: NEW_CURRENT_AND_KEY Rovnaké ako FilesystemIterator :: KEY_AS_FILENAME | FilesystemIterator :: CURRENT_AS_FILEINFO.
    • FilesystemIterator :: SKIP_DOTS Preskočí bodkové súbory (. A ..).
    • FilesystemIterator :: UNIX_PATHS Vynúti všetky cesty, aby používali spätnú lomku v štýle Unix, bez ohľadu na predvolené nastavenia systému.

Rozdiel v týchto iterátoroch spočíva v ich použití na navigáciu po danej ceste.

FilesystemIterator

Použite FilesystemIterator veľmi jednoduché.
Príklad ukazuje vyhľadávanie všetkých súborov a adresárov, ktorých názvy začínajú na „te“.

getFilename (), "te") === 0): $ arFileList = $ obFile-> getFilename (); koniec Ak; endforeach; // Vytlačí výsledok var_dump ($ arFileList); ?> Vo výstupe dostaneme nasledujúci výsledok: pole (2) (=> reťazec (7) "test.js" => reťazec (9) "test.html")

Príklad použitia iného iterátora RegexIterator nájsť všetky súbory a adresáre, ktoré končia na „t.js“ alebo „t.php“. Iterátor RegexIterator sa používa na filtrovanie výsledku a používa motor regulárneho výrazu.

getFilename (); endforeach; // Vytlačí výsledok var_dump ($ arFileList); ?> Vo výstupe dostaneme nasledujúci výsledok: pole (2) (=> reťazec (10) "script.php" => reťazec (7) "test.js")

RecursiveDirectoryIterator

Iterátor RecursiveDirectoryIterator poskytuje rozhranie na rekurzívne prechádzanie adresármi súborového systému. Má viacero užitočných metód ako napr getChildren () a má deti (), ktoré vrátia iterátor pre aktuálne umiestnenie, ak je to adresár, a skontrolujú, či aktuálny vstupný bod je adresár.


RecursiveDirectoryIterator a getChildren (). getChildren (), "/t\.(txt|css)$/"); $ arFileList = pole (); foreach ($ rxIterator ako $ obFile): $ arFileList = $ obFile-> getFilename (); endforeach; // Vytlačí výsledok var_dump ($ arFileList); ?> Vo výstupe dostaneme v tomto prípade nasledujúci výsledok - ide o súbor z adresára "Používateľ": pole (1) (=> reťazec (8) "test.txt")

GlobIterator

Iterátor GlobIterator prechádza súborom rovnakým spôsobom. Prvý atribút môže obsahovať vzor názvu.


Príklad ukazuje použitie GlobIterator s rovnakým výsledkom ako predtým.getFilename (); endforeach; // Vytlačí výsledok var_dump ($ arFileList); ?> Vo výstupe dostaneme nasledujúci výsledok: pole (2) (=> reťazec (10) "/test.html" => reťazec (8) "/test.js")

Záver

Vyššie uvedené príklady sa zamerali na rôzne techniky PHP na dosiahnutie rovnakého cieľa: získanie zoznamu súborov a adresárov.

Z príkladov možno rozlíšiť tieto hlavné body:

V tejto lekcii sa budeme zaoberať typickou úlohou, ktorá vzniká pri práci na projekte PHP: získanie zoznamu súborov a adresárov. Poďme diskutovať o niekoľkých základných a sofistikovanejších prístupoch, pričom uvedieme výhody a nevýhody každého z nich. Prvé tri riešenia budú používať všeobecné funkcie PHP a potom predstavia robustnejšie riešenie pomocou iterátorov SPL.

Pre vecnú diskusiu o riešení a demonštráciách predpokladajme, že adresárová štruktúra je takáto:

\ --- manažér | \ --- používateľ | \ --- document.txt | \ --- data.dat | \ --- style.css | --- article.txt | --- master.dat | --- script.php | --- test.dat | --- text.txt

Základné riešenia

Prvá sada riešení sa opiera o funkciu glob (), kombináciu funkcií opendir (), readdir () a closedir () a tiež funkciu scandir ().

Použitie glob ()

Prvé riešenie sa spolieha na funkciu glob (), ktorá umožňuje hľadanie cesty pomocou vzorov. Funkcia má dva parametre:

  • $ vzor (povinné): vzor vyhľadávania
  • $ flags (voliteľné): jeden alebo viac príznakov, ktorých popis nájdete v dokumentácii

Pozrime sa na niekoľko príkladov. Ak chcete v adresári vyhľadať všetky súbory a adresáre, ktorých názvy končia na .TXT, mal by sa použiť kód:

Ak vytlačíme premennú $ filelist, dostaneme:

Pole (0 => "clanok.txt", 1 => "text.txt")

Ak potrebujete zoznam súborov a adresárov, ktorých názvy začínajú na „te“, kód bude vyzerať takto:

A výstup vyzerá takto:

Pole (0 => "test.dat", 1 => "text.txt")

A ak chcete získať zoznam iba adresárov s názvami obsahujúcimi „ma“, použite kód:

Posledný príklad vypíše:

Pole (0 => "správca")

Všimnite si, že posledný príklad používa príznak GLOB_ONLYDIR ako druhý parameter funkcie. Preto bol súbor master.dat vylúčený zo zoznamu. Hoci sa funkcia glob () používa veľmi jednoducho, niekedy nie je dostatočne flexibilná. Napríklad neexistuje žiadny príznak na získanie iba súborov (žiadne adresáre), ktoré zodpovedajú vzoru.

Používame opendir (), readdir () a closedir ().

Druhým prístupom k výpisu súborov a adresárov, o ktorom budeme diskutovať, je použitie funkcií opendir (), readdir () a closedir ().

Opendir () otvorí adresár a vráti handle na pripojenie. Po získaní deskriptora je možné použiť funkciu readdir (). Pri každom volaní táto funkcia udáva názov ďalšieho súboru alebo adresára v otvorenom adresári. Ak už boli uvedené všetky mená, funkcia sa vráti falošné... Funkcia closedir () sa používa na zatvorenie deskriptora.

Na rozdiel od použitia funkcie glob () je tento prístup komplikovanejší, pretože nemáte parametre, ktoré by pomohli filtrovať zoznam vrátených názvov súborov a adresárov. Aby ste dosiahli požadovaný výsledok, musíte vykonať filtrovanie sami.

Nasledujúci príklad vráti zoznam názvov súborov a adresárov začínajúcich na „te“:

Po vykonaní vyššie uvedeného kódu bude vstupná premenná $ obsahovať inklúzie, ako napríklad „.“ a "..". Toto sú dva virtuálne adresáre, ktoré sa nachádzajú v každom adresári v súborovom systéme. Predstavujú aktuálny adresár a nadradený adresár.

Druhý príklad vytlačí iba súbory obsiahnuté v danom adresári.

Príklad poskytne nasledovné:

Pole (0 => "article.txt", 1 => "master.dat", 2 => "script.php", 3 => "test.dat", 4 => "text.txt")

Pomocou scandir ()

Na záver si predstavme funkciu scandir (). Má len jeden povinný parameter: cestu na čítanie. Funkcia vráti pole súborov a adresárov umiestnených na zadanej ceste. Ak chcete získať zoznam súborov a adresárov podľa určitého kritéria, musíte vykonať dodatočné filtrovanie. Na druhej strane je riešenie stručnejšie a nevyžaduje správu deskriptorov.

Tento príklad ukazuje, ako získať zoznam súborov a adresárov, ktorých názvy začínajú na „te“:

Použitie iterátorov SPL

Teraz sa pozrime na používanie iterátorov SPL. Ale skôr, než začneme riešiť náš problém, predstavme si knižnicu SPL a iterátory. SPL poskytuje sériu tried pre objektovo orientované dátové štruktúry, iterátory, deskriptory súborov a ďalšie.

Jednou z výhod iterátorov je, že ide o triedy a možno ich rozšíriť tak, aby vyhovovali vašim vlastným potrebám. Ďalším plusom je, že iterátory majú svoje vlastné metódy, ktoré sú užitočné pri riešení mnohých bežných problémov a sú umiestnené na jednom mieste. Pozrite si príklad použitia FilesystemIterator oproti readdir (). Obidve metódy používajú slučku, ale v prípade readdir () spracovávate iba reťazec, zatiaľ čo FilesystemIterator pracuje s objektom, ktorý môže obsahovať ďalšie informácie o súbore alebo adresári (veľkosť, vlastník, oprávnenia atď.).

PHP samozrejme poskytuje možnosť získať tieto informácie pomocou funkcií ako veľkosť súboru () a vlastník súboru (). Ale PHP5 je založené na použití konceptu OOP. Preto je lepšie využívať moderné metódy práce s programovacím jazykom. Na našej stránke sú návody venované práci s iterátormi.

Ako je uvedené vo vodnej časti tutoriálu, pozrieme sa na používanie FilesystemIterator, RecursiveDirectoryIterator a GlobIterator. Prvý z nich dedí z DirectoryIterator a zvyšok z FilesystemIterator. Všetky majú rovnaký konštruktor, ktorý má dva parametre:

  • $ cesta (povinné): cesta k položke súborového systému, s ktorou sa má pracovať
  • $ flags (voliteľné): jeden alebo viac príznakov uvedených v dokumentácii

Skutočný rozdiel v týchto iterátoroch je v tom, ako sa používajú na navigáciu po danej ceste.

FilesystemIterator

FilesystemIterator sa používa veľmi jednoducho. Pozrime sa na to v praxi. Tu sú dva príklady. Prvý zobrazuje vyhľadávanie všetkých súborov a adresárov, ktorých názvy začínajú na „te“. Druhý príklad používa iný iterátor, RegexIterator, na nájdenie všetkých súborov a adresárov, ktoré končia na „t.dat“ alebo „t.php“. RegexIterator sa používa na filtrovanie výsledku na základe regulárnych výrazov.

getFilename (), "te") === 0) ($ zoznam súborov = $ záznam-> getFilename ();))

Vyššie uvedený kód poskytne výsledok podobný predchádzajúcim príkladom.

Druhý príklad použitia RegexIterator:

getFilename (); )

Výstupom bude:

Pole (0 => "script.php", 1 => "test.dat")

RecursiveDirectoryIterator

RecursiveDirectoryIterator poskytuje rozhranie na rekurzívne prechádzanie adresármi v súborovom systéme. Má niekoľko užitočných metód, ako napríklad getChildren () a hasChildren (), ktoré vracajú iterátor pre aktuálne umiestnenie, ak ide o adresár, a kontrolujú, či je aktuálnym vstupným bodom adresár. Nasledujúci príklad ukazuje použitie RecursiveDirectoryIterator a getChildren (). Výsledok bude rovnaký ako v predchádzajúcich príkladoch.

getChildren (), "/t\.(php|dat)$/"); $ zoznam súborov = pole (); foreach ($ filter ako $ záznam) ($ zoznam súborov = $ záznam-> getFilename ();)

GlobIterator

GlobIterator iteruje cez súborový systém rovnakým spôsobom ako funkcia glob (). Prvý parameter môže obsahovať zástupný znak názvu. Príklad ukazuje použitie GlobIterator s rovnakým výsledkom ako predtým.

getFilename (); )

Záver

Táto lekcia ukazuje použitie rôznych prístupov na dosiahnutie rovnakého cieľa: získanie zoznamu súborov a adresárov. Mali by sa pamätať na tieto kľúčové body:

  • Funkcia glob () je vstavané riešenie, ale nie je dostatočne flexibilné.
  • Riešenie založené na opendir (), readdir () a closedir () je zložitejšie a vyžaduje dodatočné filtrovanie, ale je flexibilnejšie.
  • Funkcia scandir () vyžaduje dodatočné filtrovanie, ale funguje bez spracovania deskriptora.
  • Ak používate prístup OOP, mali by ste použiť knižnicu SPL. Okrem toho môžete triedy rozšíriť o svoje vlastné funkcie.
  • GlobIterator má funkciu predfiltra, zatiaľ čo iné používajú RegexIterator.