PHP Object Introspection

30 November -0001
by Justin Klein Keane
June 6, 2006

Object introspection is an often overlooked feature in PHP. With the advent of PHP 5 there are all sorts of new additions to the world of PHP object introspection as well. While easy to understand in an abstract, object introspection is a bit more difficult to envision in a real world scenario for most developers.

Object introspection refers to the ability of a class object to reveal information about itself, such as methods and variables. This might seem a little useless at first. After all, if the developer can view the code he or she can easily browse the source to determine the components of a given class. However, there is a common use for object introspection. It is most often used in conjunction with factory classes. A factory class is a special class that creates other objects. This becomes useful if you have a script that can accept variable input and produce different objects depending on the inputs. Using this model a factory class can intercept the input, determine the type of class to produce, then create a new instance of this class. If the factory class code is truly abstract then it may be impossible to tell by looking at the code what sort of class will be produced by the factory.

This is where object introspection comes into play. Using the PHP functions get_object_vars(), get_parent_class(), and get_class_methods() it is very easy to determine the composition of a given class or object. The purpose of polling this information is usually to determine variables that exist, perhaps to reset them or manipulate them, or to determine if the object initialized properly. With PHP 5 it becomes possible to simplify the task of the developer and enforce certain object constructs that may aid in determining unknown objects' composition. Using interface and abstract classes certain objects can be pre-defined. For instance, using an interface forces any class extending the interface to override the methods declared in the interface. The following code:

interface Foo {
	public function get_results();
	public function set_results($id);
}

Will force any object that extends Foo to declare the functions get_results() and set_results() where set_results() will accept one input variable named $id. In this way you can construct your class libraries so that they must conform to certain conventions.

Abstract classes are similar in many ways to interfaces. The main difference between an abstract and an interface is that abstracts allow some control over how the declared methods are defined. For instance, the following code:

abstract class Bar {
	public function print_vars() {
		print get_object_vars();
	}
	abstract protected function some_method();
}

Allows for any class that extends Bar to access the print_vars() method. Since the method is abstract it is defined and does not have to be declared. The second method, some_method(), sets up an abstract method. This method can be overridden by any child classes, however, so it serves only to enforce the visibility (for instance, with the protected keyword any child method of the same name must be either public or protected, but not private).

With some careful planning, a developer can utilize abstract classes and interfaces to set up frameworks for other classes in the application. In this way the developer can expect certain criteria to be met by various classes so that object introspection isn't quite as necessary.