Nette Documentation Preview

syntax
Kereső: Fájlkeresés
*******************

.[perex]
Meg kell találnia egy bizonyos maszknak megfelelő fájlokat? A Finder segíthet. Ez egy sokoldalú és gyors eszköz a könyvtárstruktúra böngészésére.


Telepítés:

```shell
composer require nette/utils
```

A példák feltételezik egy alias létrehozását:

```php
use Nette\Utils\Finder;
```


A  használata .[#toc-using]
---------------------------

Először is nézzük meg, hogyan használhatjuk a [api:Nette\Utils\Finder] programot a `.txt` és `.md` kiterjesztésű fájlnevek listázására az aktuális könyvtárban:

```php
foreach (Finder::findFiles(['*.txt', '*.md']) as $name => $file) {
	echo $file;
}
```

A keresés alapértelmezett könyvtára az aktuális könyvtár, de ezt az [in() vagy from() |#Where to search?] metódusokkal megváltoztathatjuk.
A `$file` változó a [FileInfo |#FileInfo] osztály egy példánya, amely sok hasznos metódussal rendelkezik. A `$name` kulcs a fájl elérési útvonalát tartalmazza sztringként.


Mit keressünk? .[#toc-what-to-search-for]
-----------------------------------------

A `findFiles()` módszer mellett létezik a `findDirectories()`, amely csak a könyvtárakban keres, és a `find()`, amely mindkettőben keres. Ezek a metódusok statikusak, tehát példány létrehozása nélkül hívhatók. A maszk paraméter opcionális, ha nem adjuk meg, mindent átkutat.

```php
foreach (Finder::find() as $file) {
	echo $file; // most már minden fájl és könyvtár fel van sorolva.
}
```

A `files()` és a `directories()` metódusokkal adhatjuk meg, hogy mit keressünk még. A metódusok ismételten meghívhatók, és paraméterként megadható a maszkok tömbje:

```php
Finder::findDirectories('vendor') // az összes könyvtárat
	->files(['*.php', '*.phpt']); // valamint az összes PHP fájl
```

A statikus módszerek alternatívája, hogy létrehozunk egy példányt a `new Finder` segítségével (az így létrehozott friss objektum nem keres semmit), és megadjuk, hogy mit keressünk a `files()` és a `directories()` segítségével:

```php
(new Finder)
	->directories() // az összes könyvtárat
	->files('*.php'); // valamint az összes PHP fájl
```

Használhat [vadkártyákat |#wildcards] `*`, `**`, `?` and `[...]` a maszkban. Megadhat könyvtárakat is, például a `src/*.php` a `src` könyvtárban található összes PHP-fájlt megkeresi.

A szimbolikus hivatkozások szintén könyvtáraknak vagy fájloknak minősülnek.


Hol keressünk? .[#toc-where-to-search]
--------------------------------------

Az alapértelmezett keresési könyvtár az aktuális könyvtár. Ezt a `in()` és a `from()` módszerekkel módosíthatja. Amint a metódusnevekből látható, a `in()` csak az aktuális könyvtárban keres, míg a `from()` annak alkönyvtáraiban is (rekurzívan). Ha rekurzívan akarsz keresni az aktuális könyvtárban, használhatod a `from('.')`.

Ezeket a metódusokat többször is meg lehet hívni, vagy több elérési utat is átadhatunk nekik tömbként, akkor a fájlok minden könyvtárban keresésre kerülnek. Ha az egyik könyvtár nem létezik, akkor a `Nette\UnexpectedValueException` eredményt kapjuk.

```php
Finder::findFiles('*.php')
	->in(['src', 'tests']) // közvetlenül a src/ és tests/ fájlokban keres.
	->from('vendor'); // keres a vendor/ alkönyvtárakban is
```

A relatív elérési utak az aktuális könyvtárhoz képest relatívak. Természetesen abszolút elérési utak is megadhatók:

```php
Finder::findFiles('*.php')
	->in('/var/www/html');
```

Wildcards [wildcards |#wildcards] `*`, `**`, `?` can be used in the path. For example, you can use the path `src/*/*.php` a `src` könyvtár második szintű könyvtáraiban található összes PHP fájl kereséséhez. A `**` karakter, az úgynevezett globstar egy erős aduász, mert lehetővé teszi az alkönyvtárakban való keresést is: a `src/**/tests/*.php` használatával a `tests` könyvtárban található összes PHP-fájlt kereshetjük, amelyek a `src` könyvtárban vagy annak bármelyik alkönyvtárában találhatók.

Másrészt a jokerek `[...]` karakterek nem támogatottak az elérési útvonalban, azaz nincs speciális jelentésük, hogy elkerüljük a nem kívánt viselkedést abban az esetben, ha például a `in(__DIR__)` címre keresünk, és véletlenül `[]` karakterek jelennek meg az elérési útvonalban.

A fájlok és könyvtárak mélységi keresésekor a rendszer először a szülő könyvtárat adja vissza, majd az abban található fájlokat, ami a `childFirst()` segítségével megfordítható.


Jokerjelek .[#toc-wildcards]
----------------------------

A maszkban több speciális karaktert is használhat:

- `*` - replaces any number of arbitrary characters (except `/`)
- `**` - tetszőleges számú tetszőleges karaktert helyettesít, beleértve a `/`-t is (azaz többszintű keresés is lehetséges).
- `?` - replaces one arbitrary character (except `/`)
- `[a-z]` - egy karaktert helyettesít a szögletes zárójelben lévő karakterek listájából.
- `[!a-z]` - egy karaktert helyettesít a szögletes zárójelben lévő karakterek listáján kívül.

Használati példák:

- `img/?.png` - `0.png`, `1.png`, `x.png`, stb.
- `logs/[0-9][0-9][0-9][0-9]-[01][0-9]-[0-3][0-9].log` - naplófájlok a következő formátumban `YYYY-MM-DD`
- `src/**/tests/*` - a `src/tests`, `src/foo/tests`, `src/foo/bar/tests` stb. könyvtárban található fájlok.
- `docs/**.md` - a `.md` kiterjesztésű összes fájl a könyvtár összes alkönyvtárában. `docs`


A  kivételével. .[#toc-excluding]
---------------------------------

A `exclude()` módszerrel kizárhat fájlokat és könyvtárakat a keresésből. Megad egy maszkot, amelynek a fájl nem felelhet meg. Példa a `*.txt` fájlok keresésére, kivéve azokat, amelyek nevében szerepel az `X` betű:

```php
Finder::findFiles('*.txt')
	->exclude('*X*');
```

A `exclude()` használatával kihagyhatja a böngészett alkönyvtárakat:

```php
Finder::findFiles('*.php')
	->from($dir)
	->exclude('temp', '.git')
```


Szűrés: .[#toc-filtering]
-------------------------

A Finder többféle módszert kínál a találatok szűrésére (azaz csökkentésére). Ezeket kombinálhatja és többször is meghívhatja.

A `size()` segítségével szűrhet a fájlméret szerint. Így a 100 és 200 bájt közötti méretű fájlokat találjuk meg:

```php
Finder::findFiles('*.php')
	->size('>=', 100)
	->size('<=', 200);
```

A `date()` módszer a fájl utolsó módosításának dátuma alapján szűr. Az értékek lehetnek abszolút vagy az aktuális dátumhoz és időhöz viszonyítottak, például így találjuk meg az elmúlt két hétben módosított fájlokat:

```php
Finder::findFiles('*.php')
	->date('>', '-2 weeks')
	->from($dir)
```

Mindkét függvény érti a `>`, `>=`, `<`, `<=`, `=`, `!=`, `<>` operátorokat.

A Finder lehetővé teszi az eredmények szűrését egyéni függvények segítségével is. A függvény paraméterként egy `Nette\Utils\FileInfo` objektumot kap, és vissza kell adnia a `true` címet ahhoz, hogy a fájl bekerüljön az eredmények közé.

Példa: A `Nette` karakterláncot tartalmazó PHP-fájlok keresése (nagy- és kisbetűket nem érzékeny):

```php
Finder::findFiles('*.php')
	->filter(fn($file) => strcasecmp($file->read(), 'Nette') === 0);
```


Mélységi szűrés .[#toc-depth-filtering]
---------------------------------------

Rekurzív keresés esetén a `limitDepth()` módszerrel beállíthatja a maximális feltérképezési mélységet. A `limitDepth(1)` beállítása esetén csak az első alkönyvtárak kerülnek feltérképezésre, a `limitDepth(0)` letiltja a mélységi feltérképezést, a -1 érték pedig törli a korlátozást.

A Finder lehetővé teszi, hogy saját függvényei segítségével döntse el, melyik könyvtárba lépjen be a böngészés során. A függvény paraméterként egy `Nette\Utils\FileInfo` objektumot kap, és a könyvtárba való belépéshez vissza kell adnia a `true` értéket:

```php
Finder::findFiles('*.php')
	->descentFilter($file->getBasename() !== 'temp');
```


Rendezés .[#toc-sorting]
------------------------

A Finder több funkciót is kínál az eredmények rendezésére.

A `sortByName()` módszer az eredményeket fájlnév szerint rendezi. A rendezés természetes, azaz helyesen kezeli a nevekben szereplő számokat, és például a `foo1.txt` -t a `foo10.txt` előtt adja vissza.

A Finder lehetővé teszi az egyéni funkcióval történő rendezést is. Ez két `Nette\Utils\FileInfo` objektumot vesz fel paraméterként, és az összehasonlítás eredményét kell visszaadnia az operátorral `<=>`, azaz `-1`, `0` nebo `1`. Például így rendezzük a fájlokat méret szerint:

```php
$finder->sortBy(fn($a, $b) => $a->getSize() <=> $b->getSize());
```


Több különböző keresés .[#toc-multiple-different-searches]
----------------------------------------------------------

Ha több különböző helyen lévő vagy különböző feltételeknek megfelelő fájlt kell keresnie, használja a `append()` módszert. Ez egy új `Finder` objektumot ad vissza, így a metódushívások láncolhatók:


```php
($finder = new Finder) // tároljuk az első Finder-t a $finder változóban!
	->files('*.php') // *.php fájlokat keresünk a src/ könyvtárban.
	->from('src')
	->append()
	->files('*.md') // a docs/-ban keres *.md fájlokat
	->from('docs')
	->append()
	->files('*.json'); // az aktuális mappában keressük a *.json fájlokat.
```

Alternatívaként használhatja a `append()` metódust egy adott fájl (vagy fájlok tömbjének) hozzáadásához. Ekkor ugyanazt az objektumot adja vissza `Finder`:

```php
$finder = Finder::findFiles('*.txt')
	->append(__FILE__);
```


FileInfo .[#toc-fileinfo]
-------------------------

A[Nette\Utils\FileInfo |api:] egy osztály, amely egy fájlt vagy könyvtárat reprezentál a keresési eredményekben. Ez a [SplFileInfo |php:SplFileInfo] osztály kiterjesztése, amely olyan információkat szolgáltat, mint a fájl mérete, utolsó módosítás dátuma, neve, elérési útja stb.

Ezen kívül metódusokat biztosít a relatív elérési utak visszaadására, ami hasznos a mélységi böngészés során:

```php
foreach (Finder::findFiles('*.jpg')->from('.') as $file) {
	$absoluteFilePath = $file->getRealPath();
	$relativeFilePath = $file->getRelativePathname();
}
```

Vannak módszerei a fájl tartalmának olvasására és írására is:

```php
foreach ($finder as $file) {
    $contents = $file->read();
    // ...
    $file->write($contents);
}
```


Eredmények visszaadása tömbként .[#toc-returning-results-as-an-array]
---------------------------------------------------------------------

Amint a példákban láttuk, a Finder megvalósítja a `IteratorAggregate` interfészt , így a `foreach` segítségével böngészhetünk az eredmények között. Úgy van programozva, hogy az eredmények csak a böngészés közben töltődnek be, így ha nagyszámú fájlod van, nem várja meg, hogy mindet beolvassa.

A `collect()` metódus segítségével az eredményeket `Nette\Utils\FileInfo` objektumok tömbjeként is visszakaphatja. A tömb nem asszociatív, hanem numerikus.

```php
$array = $finder->findFiles('*.php')->collect();
```

Kereső: Fájlkeresés

Meg kell találnia egy bizonyos maszknak megfelelő fájlokat? A Finder segíthet. Ez egy sokoldalú és gyors eszköz a könyvtárstruktúra böngészésére.

Telepítés:

composer require nette/utils

A példák feltételezik egy alias létrehozását:

use Nette\Utils\Finder;

A használata

Először is nézzük meg, hogyan használhatjuk a Nette\Utils\Finder programot a .txt és .md kiterjesztésű fájlnevek listázására az aktuális könyvtárban:

foreach (Finder::findFiles(['*.txt', '*.md']) as $name => $file) {
	echo $file;
}

A keresés alapértelmezett könyvtára az aktuális könyvtár, de ezt az in() vagy from() metódusokkal megváltoztathatjuk. A $file változó a FileInfo osztály egy példánya, amely sok hasznos metódussal rendelkezik. A $name kulcs a fájl elérési útvonalát tartalmazza sztringként.

Mit keressünk?

A findFiles() módszer mellett létezik a findDirectories(), amely csak a könyvtárakban keres, és a find(), amely mindkettőben keres. Ezek a metódusok statikusak, tehát példány létrehozása nélkül hívhatók. A maszk paraméter opcionális, ha nem adjuk meg, mindent átkutat.

foreach (Finder::find() as $file) {
	echo $file; // most már minden fájl és könyvtár fel van sorolva.
}

A files() és a directories() metódusokkal adhatjuk meg, hogy mit keressünk még. A metódusok ismételten meghívhatók, és paraméterként megadható a maszkok tömbje:

Finder::findDirectories('vendor') // az összes könyvtárat
	->files(['*.php', '*.phpt']); // valamint az összes PHP fájl

A statikus módszerek alternatívája, hogy létrehozunk egy példányt a new Finder segítségével (az így létrehozott friss objektum nem keres semmit), és megadjuk, hogy mit keressünk a files() és a directories() segítségével:

(new Finder)
	->directories() // az összes könyvtárat
	->files('*.php'); // valamint az összes PHP fájl

Használhat vadkártyákat *, **, ? and [...] a maszkban. Megadhat könyvtárakat is, például a src/*.php a src könyvtárban található összes PHP-fájlt megkeresi.

A szimbolikus hivatkozások szintén könyvtáraknak vagy fájloknak minősülnek.

Az alapértelmezett keresési könyvtár az aktuális könyvtár. Ezt a in() és a from() módszerekkel módosíthatja. Amint a metódusnevekből látható, a in() csak az aktuális könyvtárban keres, míg a from() annak alkönyvtáraiban is (rekurzívan). Ha rekurzívan akarsz keresni az aktuális könyvtárban, használhatod a from('.').

Ezeket a metódusokat többször is meg lehet hívni, vagy több elérési utat is átadhatunk nekik tömbként, akkor a fájlok minden könyvtárban keresésre kerülnek. Ha az egyik könyvtár nem létezik, akkor a Nette\UnexpectedValueException eredményt kapjuk.

Finder::findFiles('*.php')
	->in(['src', 'tests']) // közvetlenül a src/ és tests/ fájlokban keres.
	->from('vendor'); // keres a vendor/ alkönyvtárakban is

A relatív elérési utak az aktuális könyvtárhoz képest relatívak. Természetesen abszolút elérési utak is megadhatók:

Finder::findFiles('*.php')
	->in('/var/www/html');

Wildcards wildcards *, **, ? can be used in the path. For example, you can use the path src/*/*.php a src könyvtár második szintű könyvtáraiban található összes PHP fájl kereséséhez. A ** karakter, az úgynevezett globstar egy erős aduász, mert lehetővé teszi az alkönyvtárakban való keresést is: a src/**/tests/*.php használatával a tests könyvtárban található összes PHP-fájlt kereshetjük, amelyek a src könyvtárban vagy annak bármelyik alkönyvtárában találhatók.

Másrészt a jokerek [...] karakterek nem támogatottak az elérési útvonalban, azaz nincs speciális jelentésük, hogy elkerüljük a nem kívánt viselkedést abban az esetben, ha például a in(__DIR__) címre keresünk, és véletlenül [] karakterek jelennek meg az elérési útvonalban.

A fájlok és könyvtárak mélységi keresésekor a rendszer először a szülő könyvtárat adja vissza, majd az abban található fájlokat, ami a childFirst() segítségével megfordítható.

Jokerjelek

A maszkban több speciális karaktert is használhat:

  • * – replaces any number of arbitrary characters (except /)
  • ** – tetszőleges számú tetszőleges karaktert helyettesít, beleértve a /-t is (azaz többszintű keresés is lehetséges).
  • ? – replaces one arbitrary character (except /)
  • [a-z] – egy karaktert helyettesít a szögletes zárójelben lévő karakterek listájából.
  • [!a-z] – egy karaktert helyettesít a szögletes zárójelben lévő karakterek listáján kívül.

Használati példák:

  • img/?.png – 0.png, 1.png, x.png, stb.
  • logs/[0-9][0-9][0-9][0-9]-[01][0-9]-[0-3][0-9].log – naplófájlok a következő formátumban YYYY-MM-DD
  • src/**/tests/* – a src/tests, src/foo/tests, src/foo/bar/tests stb. könyvtárban található fájlok.
  • docs/**.md – a .md kiterjesztésű összes fájl a könyvtár összes alkönyvtárában. docs

A kivételével.

A exclude() módszerrel kizárhat fájlokat és könyvtárakat a keresésből. Megad egy maszkot, amelynek a fájl nem felelhet meg. Példa a *.txt fájlok keresésére, kivéve azokat, amelyek nevében szerepel az X betű:

Finder::findFiles('*.txt')
	->exclude('*X*');

A exclude() használatával kihagyhatja a böngészett alkönyvtárakat:

Finder::findFiles('*.php')
	->from($dir)
	->exclude('temp', '.git')

Szűrés:

A Finder többféle módszert kínál a találatok szűrésére (azaz csökkentésére). Ezeket kombinálhatja és többször is meghívhatja.

A size() segítségével szűrhet a fájlméret szerint. Így a 100 és 200 bájt közötti méretű fájlokat találjuk meg:

Finder::findFiles('*.php')
	->size('>=', 100)
	->size('<=', 200);

A date() módszer a fájl utolsó módosításának dátuma alapján szűr. Az értékek lehetnek abszolút vagy az aktuális dátumhoz és időhöz viszonyítottak, például így találjuk meg az elmúlt két hétben módosított fájlokat:

Finder::findFiles('*.php')
	->date('>', '-2 weeks')
	->from($dir)

Mindkét függvény érti a >, >=, <, <=, =, !=, <> operátorokat.

A Finder lehetővé teszi az eredmények szűrését egyéni függvények segítségével is. A függvény paraméterként egy Nette\Utils\FileInfo objektumot kap, és vissza kell adnia a true címet ahhoz, hogy a fájl bekerüljön az eredmények közé.

Példa: A Nette karakterláncot tartalmazó PHP-fájlok keresése (nagy- és kisbetűket nem érzékeny):

Finder::findFiles('*.php')
	->filter(fn($file) => strcasecmp($file->read(), 'Nette') === 0);

Mélységi szűrés

Rekurzív keresés esetén a limitDepth() módszerrel beállíthatja a maximális feltérképezési mélységet. A limitDepth(1) beállítása esetén csak az első alkönyvtárak kerülnek feltérképezésre, a limitDepth(0) letiltja a mélységi feltérképezést, a –1 érték pedig törli a korlátozást.

A Finder lehetővé teszi, hogy saját függvényei segítségével döntse el, melyik könyvtárba lépjen be a böngészés során. A függvény paraméterként egy Nette\Utils\FileInfo objektumot kap, és a könyvtárba való belépéshez vissza kell adnia a true értéket:

Finder::findFiles('*.php')
	->descentFilter($file->getBasename() !== 'temp');

Rendezés

A Finder több funkciót is kínál az eredmények rendezésére.

A sortByName() módszer az eredményeket fájlnév szerint rendezi. A rendezés természetes, azaz helyesen kezeli a nevekben szereplő számokat, és például a foo1.txt -t a foo10.txt előtt adja vissza.

A Finder lehetővé teszi az egyéni funkcióval történő rendezést is. Ez két Nette\Utils\FileInfo objektumot vesz fel paraméterként, és az összehasonlítás eredményét kell visszaadnia az operátorral <=>, azaz -1, 0 nebo 1. Például így rendezzük a fájlokat méret szerint:

$finder->sortBy(fn($a, $b) => $a->getSize() <=> $b->getSize());

Több különböző keresés

Ha több különböző helyen lévő vagy különböző feltételeknek megfelelő fájlt kell keresnie, használja a append() módszert. Ez egy új Finder objektumot ad vissza, így a metódushívások láncolhatók:

($finder = new Finder) // tároljuk az első Finder-t a $finder változóban!
	->files('*.php') // *.php fájlokat keresünk a src/ könyvtárban.
	->from('src')
	->append()
	->files('*.md') // a docs/-ban keres *.md fájlokat
	->from('docs')
	->append()
	->files('*.json'); // az aktuális mappában keressük a *.json fájlokat.

Alternatívaként használhatja a append() metódust egy adott fájl (vagy fájlok tömbjének) hozzáadásához. Ekkor ugyanazt az objektumot adja vissza Finder:

$finder = Finder::findFiles('*.txt')
	->append(__FILE__);

FileInfo

ANette\Utils\FileInfo egy osztály, amely egy fájlt vagy könyvtárat reprezentál a keresési eredményekben. Ez a SplFileInfo osztály kiterjesztése, amely olyan információkat szolgáltat, mint a fájl mérete, utolsó módosítás dátuma, neve, elérési útja stb.

Ezen kívül metódusokat biztosít a relatív elérési utak visszaadására, ami hasznos a mélységi böngészés során:

foreach (Finder::findFiles('*.jpg')->from('.') as $file) {
	$absoluteFilePath = $file->getRealPath();
	$relativeFilePath = $file->getRelativePathname();
}

Vannak módszerei a fájl tartalmának olvasására és írására is:

foreach ($finder as $file) {
    $contents = $file->read();
    // ...
    $file->write($contents);
}

Eredmények visszaadása tömbként

Amint a példákban láttuk, a Finder megvalósítja a IteratorAggregate interfészt , így a foreach segítségével böngészhetünk az eredmények között. Úgy van programozva, hogy az eredmények csak a böngészés közben töltődnek be, így ha nagyszámú fájlod van, nem várja meg, hogy mindet beolvassa.

A collect() metódus segítségével az eredményeket Nette\Utils\FileInfo objektumok tömbjeként is visszakaphatja. A tömb nem asszociatív, hanem numerikus.

$array = $finder->findFiles('*.php')->collect();