Refleksija je koncept programiranja koji daje mogućnost softveru da sam sebe menja (svoju strukturu i ponašanje) nakon što je već pokrenut. Drugim rečima, programski jezici koji podržavaju refleksiju imaju mogućnost da sebe dinamički menjaju bez potrebe intervencije programera i ponovnog kompajliranja/pokretanja softvera nakon unesenih izmena.
PHP od verzije 5 podržava kompletan Reflection API, koji se doduše još uvek unapređuje i nije potpuno dokumentovan.
U sledećem primeru ću pokušati da predstavim osnovni koncept Refleksije. Za potrebe primera ćemo napraviti proste klase koje računaju površine tri geometrijske figure – Kruga, Kvadrata i Trougla:
<?php /** Klasa Krug racuna povrsinu kruga */ class Krug{ /** Povrsina kruga je poluprecnik na kvadrat puta Pi */ function Povrsina($r){ $P=$r*$r*3.14; return $P; } } /** Klasa Kvadrat racuna povrsinu kvadrata */ class Kvadrat{ /** Povrsina kvadrata je stranica na kvadrat */ function Povrsina($a){ $P=$a*$a; return $P; } } /** Klasa Trougao racuna povrsinu trougla */ class Trougao{ /** Povrsina trougla je stranica puta njena visina podeljeno sa dva */ function Povrsina($b,$h){ $P=$b*$h/2; return $P; } } ?>
Na osnovu izbora koji korisnik softvera unese, izračunaćemo površinu odgovarajuće geometrijske figure.
Standardni način bi bio otprilike:
<?php //Ove parametre bira korisnik, za potrebe primera ćemo ih ‘zakucati’ $Figura="Krug"; $PrviParametar=3; $DrugiParametar=6; //Na osnovu izbora racunamo odgovarajucu povrsinu if($Figura=="Krug"){ $Krug= new Krug(); echo "<br/>".$Figura." povrsina: "; echo $Krug->Povrsina($PrviParametar); } if($Figura=="Kvadrat"){ $Kvadrat= new Kvadrat(); echo "<br/>".$Figura." povrsina: "; echo $Kvadrat->Povrsina($PrviParametar); } if($Figura=="Trougao"){ $Trougao= new Trougao(); echo "<br/>".$Figura." povrsina: "; echo $Trougao->Povrsina($PrviParametar,$DrugiParametar); } ?>
Preko refleksije možemo da napišemo sledeći kod:
<?php //Instanciranje objekta odgovarajuce klase na osnovu prosledjenog imena $Reflektor = new ReflectionClass($Figura); $FigObj = $Reflektor->newInstance(); //Kreiranje metode za izracunavanje povrsine iz odgovarajuce klase $refMethod = new ReflectionMethod($Figura, 'Povrsina'); //Pozivanje metode za izracunavanje povrsine nad prethodno instanciranim //objektom, sa potrebnim parametrima $Povrsina=$refMethod->invoke($FigObj,$PrviParametar,$DrugiParametar); echo "<br/>".$Figura." povrsina: ".$Povrsina; ?>
Inače gornji kod možemo da napišemo i koristeći PHP “Variable variables” koncept:
<?php $Objekat=new $Figura(); $Povrsina=$Objekat->Povrsina($PrviParametar,$DrugiParametar); echo "<br/>".$Figura." povrsina: ".$Povrsina; ?>
Obratite pažnju da iako je Variable variables primer naizgled sličan (pa i jednostavniji) od Reflection primera, oni su ipak konceptualno potpuno drugačiji. Naime za Variable variables smo morali da znamo da postoji metoda Povrsina u nasim klasama. Sa Refleksijom možemo da u toku izvršavanja PHP koda dobijemo informacije o nepoznatim klasama i metodama koje sadrže i da na osnovu toga izvršimo odgovarajuće radnje (istini za volju u Reflection primeru smo takođe direktno pozivali metodu Povrsina).
Dodatna pomoć za parsiranje nepoznatih klasa i metoda može da bude i sposobnost Refleksije da nam vraća komentare upisane u kodu.
Na primer:
<?php $ReflKlasa = new ReflectionClass($Figura); echo "<br/>".$ReflKlasa->getDocComment(); $ReflMetoda= new ReflectionMethod($Klasa=$Figura, $Metoda="Povrsina"); echo "<br/>".$ReflMetoda->getDocComment(); ?>
U zavisnosti od geometrijske figure koju smo izabrali u $Figura, dobićemo odgovarajuće komentare. Imajte u vidu da komentari moraju da počinju sa /** kako bi getDocComment metoda radila.
Priča o Refleksiji je mnogo šira i ovo su bili najprostiji primeri na osnovu kojih možete da nastavite dalje istraživanje ovog koncepta ako vas je zainteresovao. Ovi primeri možda nemaju praktičnu upotrebu, ali pažljivim pisanjem koda, klasa i metoda, možete da omogućite da se uz pomoć Refleksije pišu softveri koji su pregledniji, prirodniji i lakši za održavanje.