Reflection API
• Interfejs
Reflection API
nie służy wyłącznie do analizy klas.
• Klasy interfejsu
Reflection API
dają bezprecedensową
możliwość dynamicznego odwoływania się informacji o
obiektach, funkcjach i wyjątkach przetwarzanych w
skryptach.
• Z racji możliwości i zakresu zastosowań interfejsu
Reflection API
należy go preferować w stosunku do
omawianych wcześniej możliwości oferowanych przez
szereg funkcji.
• Interfejs
Reflection API
odwołuje się do klasy
ReflectionClass
, która pozwala na pozyskanie informacji o
każdym niemal aspekcie badanej klasy – a działa równie
skutecznie wobec klas definiowanych przez użytkowników,
jak i wobec klas wbudowanych.
• Jedynym argumentem wywołania konstruktora klasy
ReflectionClass
jest nazwa klasy wyznaczonej do analizy.
Wybrane klasy interfejsu
Reflection API
Klasa
Opis
Reflection
Udostępnia statyczną metodę
export()
dającą informacje o klasach
ReflectionClass
Informacje i narzędzia badania klas
ReflectionMetho
d
Informacje i narzędzia badania
metod
ReflectionParam
eter
Informacje i narzędzia badania
argumentów metod
ReflectionProper
ty
Informacje i narzędzia badania
składowych
ReflectionFuncti
on
Informacje i narzędzia badania
funkcji
ReflectionExtens
ion
Informacje o rozszerzeniach PHP
ReflectionExcvep
tion
Klasa wyjątków
Reflection::export()
• Tworzymy nowy obiekt
ReflectionClass
kojarzony z nazwą badanej klasy (np.
CdProduct
).
• Następnie odwołujemy się do funkcji statycznej
$prod_class = new
ReflectionClass(‘CdProduct’);
Reflection::export( $prod_class);
• Patrz listing05.24.php
• Jak widać, metoda
Reflection::export()
daje
dostęp do znacznej ilości informacji o klasie.
Function classData()
• Tworzymy nowy obiekt
ReflectionClass
kojarzony z nazwą badanej klasy (np.
CdProduct
).
• Następnie deklarujemy funkcję
classData()
,
która ilustruje sposób pozyskiwania
niektórych informacji o badanej klasie.
• Patrz listing05.25.php
Metody ReflectionClass
• ReflectionClass::getName()
zwraca nazwę
badanej klasy.
• ReflectionClass::isUserDefined()
zwraca
true
jeśli badana klasa jest klasą definiowaną przez
użytkownika w kodzie skryptu PHP5.
• ReflectionClass::isInternal()
zwraca
true
jeśli
badana klasa jest klasą wbudowaną.
• ReflectionClass::isAbstract()
zwraca
true
jeśli
badana klasa jest klasą abstrakcyjną.
• ReflectionClass::isInterface()
zwraca
true
jeśli
badana klasa jest interfejsem.
• ReflectionClass::isInstantiable()
zwraca
true
jeśli badana klasa jest klasą dla której można
tworzyć obiekty.
ReflectionUtil
• ReflectionUtil to prosta klasa definiująca
zaledwie jedną metodę statyczną
ReflectionUtil::getClassSource().
• Patrz listing05.26.php
ReflectionClass::getFileNam
e()
• Nazwę pliku zawierającego definicję klasy udostępnia
wywołanie metody
ReflectionClass::getFileName()
;
zwrócona nazwa jest ścieżką bezwzględną, więc
można od razu otworzyć plik kodu.
• Listę wierszy kodu źródłowego z tego pliku -
pozyskiwana jest wywołaniem funkcji
file()
. Numer
pierwszego wiersza definicji klasy określa wywołanie.
Jednym argumentem jej wywołania jest obiekt klasy
ReflectionClass,
metoda zaś zwraca kod źródłowy
wskazanej klasy
ReflectionClass::getStartLine()
,
numer wiersza końcowego – wywołanie
ReflectionClass::getEndLine()
.
• Dla uzyskaniu tych danych pozostaje jedynie
pobranie (wycięcie) z tablicy interesujące nas
wiersze, wywołując funkcję
array_slice().
Badanie metod
Tak jak klasa
ReflectionClass
pośredniczy w analizie
klas, tak obiekt klasy
ReflectionMethod
pozwala na
uzyskanie informacji o metodach badanej klasy.
Obiekt klasy
ReflectionMethod
można pozyskać na
jeden z dwu sposobów z pomocą
ReflectionClass::getMethod():
Nie podając nazwy metody i korzystając z tablicy obiektów
zawierających listę pozyskanych obiektów
array_slice().
;
Podając nazwę metody i korzystając ze zwracanego obiektu
ReflectionMethod
.
Przykład pokazany na listing.05.27.php dotyczy
pierwszego ze sposobów.
Badanie metod – kod
źródłowy
• Wyodrębnianie kodu źródłowego metody jest
bardzo proste. Mówiliśmy już o zastosowaniu
metod klasy
ReflectionMethod
, które
udostępniają komplet potrzebnych informacji
z pomocą:
getFileName()
,
getStartLine()
,
getEndLine()
.
• Patrz listing05.28.php
Badanie argumentów
metody
•
Obiekt klasy
ReflectionParameter
może dawać
informację o nazwie argumentu, o tym, czy argument
jest przekazywany przez referencje (czyli został
zadeklarowany w sygnaturze metody ze znakiem
&
),
jak również o wymuszonej deklaracją klasy argumentu
i o akceptacji w jego miejsce wartości pustej.
•
Metoda
ReflectionClass::getMethod()
służy do
pozyskania obiektu klasy
ReflectionMethod
opisującego wybraną metodę.
•
Następnie, za pośrednictwem zainicjowanego na rzecz
tego obiektu wywołania metody
getParameter()
pobierana jest tablica obiektów
ReflectionParameter
.
•
Obiekty z tablicy
ReflectionParameter
są kolejno
wyodrębniane i przekazywane do funkcji
argData()
.
•
Patrz listing05.29.php
Przykład zastosowania
•
Załóżmy, że tworzymy klasę, która w sposób
dynamiczny wywołuje obiekty klasy
Module
. Chodzi o
to, aby kod mógł zaakceptować rozszerzenia i wtyczki
osób trzecich wywoływane z aplikacji bez potrzeby
ciągłego zmieniania jej kodu.
•
W tym celu zdefiniujemy w klasie bazowej
Module
metodę
execute()
, zmuszając wszystkie klasy
pochodne
Module
do implementacji tej metody.
•
Zakładamy też, że użytkownicy systemu mają mieć
możność prowadzenia listy dostępnych modułów w
zewnętrznym pliku konfiguracyjnym zapisanym w
formacie
XML
.
•
System ma na podstawie listy zgromadzić
odpowiednią liczbę obiektów
Module
i wywołać, na
rzecz każdego metodę
execute()
.
•
Patrz listing05.30.php i listing05.31.php