A PHP programozási nyelv

SPL

Bevezetés

(Standard PHP Library)

Az Standard PHP Library osztályok és interfészek gyűjteménye általános problémák megoldására. Maga PHP is nagyon keveset ír erről, és több helyen megemlíti, hogy kidolgozás alatt van a leírásuk. Lényege, hogy a beépített PHP függvényekhez biztosít egy olyan API-t, aminek köszönhetően sokkal jobban fenntartható és jobb objektum orientált kódot tudunk készíteni.

PHP 5.0-tól kiegészítésként került a nyelvbe, de még alapértelmezetten nem volt bekapcsolva. 5.3-tól pedig már nem kikapcsolható a kiegészítés, hanem a nyelv része lett.

Valós szerepe, hogy jobban felépített, érthetőbb, tesztelhetőbb, biztonságosabb programkódot írjunk. Pl. keretrendszerek készítésekor hasznos lehet.

Interfészek

Countable

A PHP-s count függvény meghívása esetén az interfészt leíró objektum saját count függvénye fut le, és számolhatóvá válik az objektum. Amennyiben egy osztály implementálja a Countable interfészt, akkor a count függvényt kell implementálni az osztályban. Érdemes figyelni arra, hogy amennyiben nem implementáljuk a Countable interfészt, de implementáljuk a count függvényt, akkor az objektumra történő PHP-s count függvény meghívása esetén 1-et fog visszaadni.

interface Countable { public function count(); }

SplObserver, SplSubject

Megfigyelő tervezési minta megvalósítása PHP-ban. Részletesebben a témáról itt lehet olvasni: http://en.wikipedia.org/wiki/Observer_pattern Az SplObserver esetén egy update metódust kell megvalósítani, amelynek egy SplSubject a paramétere. Az attach, detach, notify metódusokat kell implementálni az SplSubject-hez, amikkel fel lehet „akasztani”, és le lehet venni megfigyelőket.

OuterIterator

Az alap PHP Iterator interfészből származik. Arra használjuk, hogy iterátorokból álló adatszerkezeten megy végig, és az azon belül található interátorokon megy egyesével végig. A getInnerIterator metódussal kapja meg a belső iteratort.

RecursiveIterator

Az alap PHP Iterator interfészből származik. Rekurzívan járhatja be az iterátor szerkezetet. Metódusai: hasChildren, getChildren

A RecursiveIteratorIterator megvalósítja a RecursiveIterator-t. Pl.:

$dirIterator = new RecursiveDirectoryIterator('../'); $iterator = new RecursiveIteratorIterator($dirIterator); foreach ($iterator as $file) { $prefix = str_repeat(' ', $iterator->getDepth()); echo $prefix, ' - ', $file, PHP_EOL; }

SeekableIterator

Az alap PHP Iterator interfészből származik. A seek metóduson keresztül lehet folyamatosan valamilyen index alapján lépkedtetni.

Kivételek

A kivételkezelésben is új alternatívát szolgál, a saját magunk által megírt kivételek helyet. Több hasznos kivét lett definiálva az SPL-ben. Az alábbiakban felsoroljuk a leghasznosabbakat, és rövid leírás mutatunk felhasználásukról.

LogicException

Közvetlenül a szoftver működéséhez kapcsolódó kivétel, amely a program logikájában való hibára mutat. Ezen hibák a kódban való javítást igényelnek.

DomainException

A LogicException osztályból öröklődik. A kivétel akkor használható, ha nem felel meg egy adott üzleti logikának. Pl. van egy érték, és nem azt szeretnénk kapni az üzleti logika szerint, akkor dobunk egy ilyen kivételt.

OutOfRangeException

A LogicException osztályból öröklődik. Hibás mutatóra való hivatkozáskor használható. Kicsit hajaz a Java kivételekre.

LengthException

A LogicException osztályból öröklődik. Nem megfelelő hossz esetén használható. Pl. ha egy string túl hosszú értéket tartalmaz.

InvalidArgumentException

A LogicException osztályból öröklődik. Akkor használható, ha a kapott érték nem a várt, azaz nem megfelelő típusú. PHP-ban ez gyakran előfordul, elsősorban a mixed típusú változóknál, amik először egy string értéket tárolnak, majd később például egy tömböt.

BadFuncitonCallException

A LogicException osztályból öröklődik. Akkor használható, ha egy meghívott függvény nem található, vagy valamilyen várt paramétere hiányzik.

BadMethodCallException

A BadFuncitonCallException osztályból öröklődik. Akkor használható, ha egy osztályon hívott metódus nem található, vagy valamilyen várt paramétere hiányzik. Ez kifejezetten az objektumokra hívott függvényekre vonatkozik. Elsősorban például a __cal() magic metódusban használható, ha a keresett metódus nem található az adott osztályban.

RuntimeException

Olyan hibát jelezhetünk ezzel, amely csak futásidőben jelentkezik. Ilyen lehet, ha próbálunk betölteni egy fájlt, de az nem létezik. Az SPL osztályok használják.

OutOfBoundsException

A RuntimeException osztályból öröklődik. Hibás mutatóra való hivatkozás esetén használható, ha a hiba csak futásidőben keletkezhet. Hasonló az OutOfRangeException-höz, de ezt kifejezetten futásidejű kivételek kezelésére használjuk.

OverflowException

A RuntimeException osztályból öröklődik. Akkor használható, ha egy megtelt tárolóhoz akarunk újabb elemet hozzáadni. Ilyen lehet például az SPLFixedArray-ben.

UnderflowException

A RuntimeException osztályból öröklődik. Akkor használható, ha egy üres tárolóból próbálunk eltávolítani egy elemet.

RangeException

A RuntimeException osztályból öröklődik. Jellemzően hibás értékek esetén keletkezik, például aritmetikai hibáknál használható (pl. nullával osztás).

UnexpectepValueException

A RuntimeException osztályból öröklődik. Ha egy kapott érték nem egyezik egy meghatározott értékkel sem. Például, ha egy metódus négy konstans közül várja valamelyiket egyetlen paramétereként, de nem ennek megfelelő értéket kap.

Adatszerkezetek

A PHP alapvetően nagyon kevés adatszerkezetet tartalmazott, mivel az array-el szinte mindent meg lehet oldani. De néhány esetben hasznosabb egy specifikus adatszerkezet, amely gyorsabb végrehajtást eredményez. Régebben a nagy PHP-s projekteknél külön megírták ezeket saját használatra, majd később ezeket egy csomagba foglalták és bekerül az SPL-be.

Duplán láncolt listák

SPLStack, SPLQueue. Az általános sor, és verem megvalósítások. Az alapvető művelteket tartalmazzák. (pl.: push, pop, next)

Pl.:

$queue = new SplQueue(); $queue->push(3); $queue->push(2); $queue->push(1); echo $queue->pop() . ””; echo $queue->pop() . ””; echo $queue->pop() . ””; // Kimenet: 1 2 3

Kupac

SPLHeap, SPLMaxHeap, SPLMinHeap, SplPriorityQueue. Az alapvető kupac megvalósításokat tartalmazza.

A Max és Min kupacok rendezve tárolják az értékeket a kupacból. Pl.:

$heap->insert(1); $heap->insert(6); $heap->insert(3); foreach ($heap as $h) { echo $h . " "; } // Kimenet: 6 3 1

Tömb

SplFixedArray. Ez nem összetévesztendő a PHP-s array adatszerkezettel, mivel ez a klasszikus fix méretű tömböt reprezentálja. Elegánsabb és biztonságosabb, mint az array.

Map

SPLObjectStorage. Alapvetően egy tipikus map adatszerkezet objektumok tárolására. Az attach, detach műveletekkel lehet hozzáadni, és eltávolítani elemet a mapból.

Fájlkezelés

Az SPL-ben elkészítették a fájlkezelés egyszerű objektum orientált változatát, melyet megfelelő kivételkezeléssel, fájlbetöltéssel készítettek el. Azért hasznos, mert egy egyszerű példányosítás után könnyen iterálhatunk a fájl sorain egy foreach-el. Amennyiben nem sikerül betölteni egy fájl RuntimeException-t kapunk. Emellett a fájl objektumon az összes fájlkezeléshez kapcsolódó metódus elérhető.

$file = new SplFileObject('test.txt'); foreach ($file as $line) { echo $line; }

Autoloder

Az Spl-ben a magic method __autoloder helyet saját spl_autoloder-t készítettek, amely egy megadott metódusnévvel tud regisztrálni osztályokat.(spl_autoload_register). Azért jobb az spl-es megvalósítás, mert ha több autoloder-ünk van, akkor amennyiben ha nem találja meg az első a betöltendő osztályt, akkor azonnal próbálkozik a következő regisztrált autoloder-ben.

Pl.:

function autoload($class) { $filename = $class . '.class.php'; if (file_exists($filename)) { require_once($class . '.class.php'); } else { throw new Exception('Nincs meg az osztaly: ' . $class); } } spl_autoload_register('autoload'); new SampleClass();