در قسمت قبل دیدیم که با رفلکشن 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