Friday, June 28, 2013

ReflectionClass in PHP

To know internals of any classes or interfaces, we can use ReflectionClass which is offered by PHP5. With this, we can retrieve methods, properties etc from a class. Let's checkOut a simple example ::

<?php
// User defined class a [Line No. 2]
class a
{
  const am = 10;   // Constant
  protected $aa;   // Protected Member
  public $aaa;     // Public Member
  function disp()  {  } // Public method
}

// Inheritance [Line No. 11]
class b extends a
{
  static $vendor = 1; // Static Property
  public $bbb;        // Public property
  const am = 20;      // Constant
 
  public static function get_vendor()  { } // Static Method
  function disp(){  }    // Public Method                 
}

// Print
ReflectionClass::export( 'b' );
?>


Output ::

Class [ <user> class b extends a ] {
  @@ C:\xampp\htdocs\test.php 12-20

  - Constants [1] {
    Constant [ integer am ] { 20 }
  }

  - Static properties [1] {
    Property [ public static $vendor ]
  }

  - Static methods [1] {
    Method [ <user> static public method get_vendor ] {
      @@ C:\xampp\htdocs\test.php 18 - 18
    }
  }

  - Properties [3] {
    Property [ <default> public $bbb ]
    Property [ <default> protected $aa ]
    Property [ <default> public $aaa ]
  }

  - Methods [1] {
    Method [ <user, overwrites a, prototype a> public method disp ] {
      @@ C:\xampp\htdocs\test.php 19 - 19
    }
  }
}


Discussion ::
1. The class whose internals we want to must be passed to ReflectionClass' static method export(). For example if we want to know about a class named 'employee', we would write as this ::
  ReflectionClass::export( 'employee' );
 

2. Notice the output, Constants, Static Properties, Static Methods, Methods and Properties are shown in list. Check that in the properties section, inherited properties (3) are also shown. In the method section, notice it is denoted that class b overwrites a's disp() with its own copy of disp(). ReflectionClass' export static method returns minute details about a class like number of methods and properties, method's parameters, visibility parameters (whether private, protected or public). It also tells us about the line numbers within the source code where a particular method or property was defined.

Let's try some other method ReflectionClass offers. Check another example below ::

<?php
// Class Definition as shown above ...

// Create new ReflectionClass Object
$c = new ReflectionClass('b');

// Use ReflectionClass Methods

// Get value of a Constant 'am'
echo $c->getConstant('am');

// getConstants() returns class
// constants as an array
print_r( $c->getConstants() );

// Get Constructor Name if defined
print_r($c->getConstructor());

// Get all properties including inherited ones
print_r( $c->getDefaultProperties());

// Get the filename, in which the class is defined
echo $c->getFileName();

// GET ALL Interface Names implemented in the CLASS
// getInterfaces() returns all interfaces in
// ReflectionClass objects
print_r($c->getInterfaceNames());

// Lists all local and inherited methods
print_r($c->getMethods());

// Get the class name including NameSpace
echo $c->getName();

// Get the name of Parent Class
print_r($c->getParentClass());

// GET all properties (including inherited)
// We use various Filters with this function
// IS_PROTECTED to get Protected properties
// IS_PUBLIC to get Public properties
// IS_STATIC to get static properties
// IS_PRIVATE to get static properties
// Parent's STATIC properties are also shown
print_r($c->getProperties( ReflectionProperty::IS_STATIC  ));

// Get a Particular property
echo $c->getProperty('vendor');

// List all static Properties
print_r( $c->getStaticProperties());

// GEt value of any static property
var_dump( $c->getStaticPropertyValue('vendor'));

// Check if a specific Constant exists
echo $c->hasConstant('am');

// Check if a specific Property exists
echo $c->hasProperty('aa');

// Check if a specific Method exists
echo $c->hasMethod('disp');

// Check if a Class is Abstract
var_dump( $c->isAbstract());

// Checks if a class is clonable
// A Class is NOT clonable if its magic
// method __clone() is set to private
var_dump($c->isCloneable());

// Checks if a class is FInal
var_dump($c->isFinal());

// Checks if any object is an instance
// of the current class
var_dump( $c->isInstance(new b) );

// The above statement is similar to
echo new b instanceof b;

// Check if a class is instantiable
// Interfaces, Abstract Classes and classes
// with private constructor can not be
// instantiated
var_dump( $c->IsInstantiable() );
?>


Here I repeat some important points mentioned in comments in the code above ::

i. Interfaces, Abstract classes and any class with its constrructor ( __construct() ) set to private are not instantiable.
ii. If any class' magic method __clone() is set to private, the object of such class can not be cloned any more.
iii. Parent class' Static properties can be accessed from children classes.
iv. Parent class' Constant can be accessed from children classes.


ReflectionClass is used to make documentation for a piece of code.

No comments: