ReflectionClass

The ReflectionClass class lets you reverse-engineer classes.

<?php
  class ReflectionClass implements Reflector {
      public __construct(string name)
      public string getName()
      public bool isInternal()
      public bool isUserDefined()
      public string getFileName()
      public int getStartLine()
      public int getEndLine()
      public string getDocComment()
      public ReflectionMethod getConstructor()
      public ReflectionMethod getMethod(string name)
      public ReflectionMethod[] getMethods()
      public ReflectionProperty getProperty(string name)
      public ReflectionProperty[] getProperties()
      public array getConstants()
      public mixed getConstant(string name)
      public bool isInstantiable()
      public bool isInterface()
      public bool isFinal()
      public bool isAbstract()
      public int getModifiers()
      public bool isInstance(stdclass object)
      public stdclass newInstance(mixed* args)
      public ReflectionClass[] getInterfaces()
      public ReflectionClass getParentClass()
      public string toString()
      public bool isSubclassOf(ReflectionClass class)
  }
?>

To introspect a class, you will first have to create an instance of the ReflectionClass class. You can then call any of the above methods on this instance.

Example 14-4. Using the ReflectionClass class

<?php
  interface Serializable
  {
      // ...
  }

  class Object
  {
      // ...
  }

  /**
   * A counter class
   *
   */
  class Counter extends Object implements Serializable 
  {
      const START= 0;
      private static $c= Counter::START;

      /**
       * Invoke counter
       *
       * @access  public
       * @return  int
       */
      public function count()
      {
          return self::$c++;
      }
  }

  // Create an instance of the ReflectionClass class
  $class= new ReflectionClass('Counter');

  // Print out basic information
  printf(
      "===> The %s%s%s %s '%s' [extends %s]\n".
      "     declared in %s\n".
      "     lines %d to %d\n".
      "     having the modifiers %d [%s]\n",
      $class->isInternal() ? 'internal' : 'user-defined',
      $class->isAbstract() ? ' abstract' : '',
      $class->isFinal() ? ' final' : '',
      $class->isInterface() ? 'interface' : 'class',
      $class->getName(),
      var_export($class->getParentClass(), 1),
      $class->getFileName(),
      $class->getStartLine(),
      $class->getEndline(),
      $class->getModifiers(),
      implode(' ', Reflection::getModifierNames($class->getModifiers()))
  );

  // Print documentation comment
  printf("---> Documentation:\n %s\n", var_export($class->getDocComment(), 1));

  // Print which interfaces are implemented by this class
  printf("---> Implements:\n %s\n", var_export($class->getInterfaces(), 1));

  // Print class constants
  printf("---> Constants: %s\n", var_export($class->getConstants(), 1));

  // Print class properties
  printf("---> Properties: %s\n", var_export($class->getProperties(), 1));

  // Print class methods
  printf("---> Methods: %s\n", var_export($class->getMethods(), 1));

  // If this class is instantiable, create an instance
  if ($class->isInstantiable()) 
  {
      $counter= $class->newInstance();

      echo '---> $counter is instance? '; 
      var_dump($class->isInstance($counter));

      echo '---> new Object() is instance? ';
      var_dump($class->isInstance(new Object()));
  }
?>

Note: The method newInstance() accepts a variable number of arguments which are passed to the function just as in call_user_func().

Note: $class= new ReflectionClass('Foo'); $class->isInstance($arg) is equivalent to $arg instanceof Foo or is_a($arg, 'Foo').