در قسمت قبل دیدیم که با رفلکشن ReflectionFunction میتوانیم اجزای یک تابع را بررسی کنیم و پارامترهای تابع هم از نوع رفلکشن ReflectionParameter هستند و میتوان اجزای آنها را هم بررسی کرد. در این بخش یک کلاس تعریف میکنیم و آن را بررسی میکنیم.
ابتدا یک کلاس به نام Person
را تعریف میکنیم
<?php
/** * This is simple description about class * */
class Person
{
public $name;
private $age;
public function __construct()
{
$this->name = 'Anonymous';
}
public function setName($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
public function setAge($age)
{
$this->age = $age;
}
public function getAge()
{
return $this->age;
}
}
$rc = new ReflectionClass('Person');
echo $rc->getName(); // Person
// نام کلاس را بر میگرداند
// echo $rc->getDocComment();
// /**
// * This is simple description about class
// *
// */
// توضیحات بالای کلاس را برمیگرداند
$methods = $rc->getMethods();
// print_r($methods);
// هستند ReflectionMethod لیستی از متد های تابع را برمیگرداند که از نوع
foreach ($methods as $method) {
echo $method->getName();
// دقت میکنید که به یک ابجکت از نوع رفلکشن متد دسترسی داریم و از توابع مربط به خودش میتوانیم استفاده کنیم
echo "\n";
}
همان گونه که در کد بالا می بینبد می توانیم اجزاء کلاس و ساختار هر بخش آن را بررسی کنیم و نام کلاس getName
و با استفاده از متد getMethods
متد های کلاس را ببینیم که این متد برای یک آرایه از نوع ReflectionMethod
بر میگرداند.
ReflectionMethod
ساختاری شبیه به ReflectionFunction دارد و هر دو اینها از کلاس ReflectionFunctionAbstract ارث بری کرده اند
ReflectionFunctionAbstract implements Reflector
ReflectionFunction extends ReflectionFunctionAbstract implements Reflector
ReflectionMethod extends ReflectionFunctionAbstract implements Reflector
کلاس ReflectionFunctionAbstract شامل متد های زیر است
final private __clone ( void ) : void public getClosureScopeClass ( void ) : ReflectionClass public getClosureThis ( void ) : object public getDocComment ( void ) : string public getEndLine ( void ) : int public getExtension ( void ) : ReflectionExtension public getExtensionName ( void ) : string public getFileName ( void ) : string public getName ( void ) : string public getNamespaceName ( void ) : string public getNumberOfParameters ( void ) : int public getNumberOfRequiredParameters ( void ) : int public getParameters ( void ) : array public getReturnType ( void ) : ReflectionType public getShortName ( void ) : string public getStartLine ( void ) : int public getStaticVariables ( void ) : array public hasReturnType ( void ) : bool public inNamespace ( void ) : bool public isClosure ( void ) : bool public isDeprecated ( void ) : bool public isGenerator ( void ) : bool public isInternal ( void ) : bool public isUserDefined ( void ) : bool public isVariadic ( void ) : bool public returnsReference ( void ) : bool abstract public __toString ( void ) : void
ReflectionFunction
متد های بالا را دارد اما ReflectionMethod
متد های زیر را علاوه بر متد های بالا دارد
public static export ( string $class , string $name [, bool $return = FALSE ] ) : string public getClosure ( object $object ) : Closure public getDeclaringClass ( void ) : ReflectionClass public getModifiers ( void ) : int public getPrototype ( void ) : ReflectionMethod public invoke ( object $object [, mixed $... ] ) : mixed public invokeArgs ( object $object , array $args ) : mixed public isAbstract ( void ) : bool public isConstructor ( void ) : bool public isDestructor ( void ) : bool public isFinal ( void ) : bool public isPrivate ( void ) : bool public isProtected ( void ) : bool public isPublic ( void ) : bool public isStatic ( void ) : bool public setAccessible ( bool $accessible ) : void
با نگاهی متد های اضافه می بینم چه ویژگی هایی یک متد را از فانکشن متمایز میکند.
ایده : به لیست متد ها نگاه کنید و فکر کنید هر کدام چه کاربردی دارند یا اینکه کدام با کاربرد کدام آشنا نیستید.
به متد setAccessible دقت کنید، آیا واقعا میتوانیم دسترسی یک متد را تغییر دهیم ؟ (بررسی میکنیم)
یک کلاس تعریف میکنیم که یک متد private هم داشته باشد.
<?php
class Math
{
public static function power($num)
{
return "Power {$num} is " . self::calcPower($num);
}
private static function calcPower($num)
{
return $num * $num;
}
}
echo Math::power(2);
// Power 2 is 4
// echo Math::calcPower(2);
// PHP Fatal error: Uncaught Error: Call to private method Math::calcPower() from context ''
همان طور که انتظار داریم متد private را نمی توانیم خارج از خود کلاس صدا بزنیم(دسترسی نداریم)، اما با استفاده از رفلکشن می توانیم این کار را انجام دهیم
$rm = new ReflectionMethod('Math', 'calcPower');
$rm->setAccessible(true);
echo $rm->invoke(null, 2); // صدا زدن متد استاتیک
// 4
با استفاده از setAccessible
و invoke
توانستیم یک متد private را خارج از کلاس صدا بزنیم. (جالب بود نه)
برای پروپرتی هم ReflectionProperty داریم و می توانیم دسترسی ها را تغییر دهیم و از آنها هم استفاده کنیم.
در پایین لیست رفلکشن ها را و کلاس ها و اینترفیس های مربوط به رفلکشنها را میبینیم که می توانیم یک دید کلی در مورد آنها پیدا کنیم.
Reflector
ReflectionClassConstant implements Reflector
ReflectionProperty implements Reflector
ReflectionClass implements Reflector
ReflectionObject extends ReflectionClass implements Reflector
ReflectionZendExtension implements Reflector
ReflectionExtension implements Reflector
ReflectionFunctionAbstract implements Reflector
ReflectionFunction extends ReflectionFunctionAbstract implements Reflector
ReflectionMethod extends ReflectionFunctionAbstract implements Reflector
ReflectionType
ReflectionNamedType extends ReflectionType
ReflectionParameter implements Reflector
ReflectionGenerator
Reflection
ReflectionException extends Exception
احتمالا بررسی ReflectionObject
هم جالب خواهد بود. (تمرین)
در بخش بعد در مورد کاربرد رفلکشها می نویسم و بحث رفلکشن را تمام میکنیم.
Leave a Reply