Introducing the Reflection API in PHP 5

In this first part of a series, we’ll begin exploring some of the methods included with the Reflection API bundled with PHP 5. The interface allows developers to collect relevant information about a reflected class, including its name, its declared constants and properties, in a extremely straightforward way.

Even though PHP is intrinsically a weakly-typed language, as it doesn’t internally impose any constraints on the types of values that can be held by a given variable (with the exception of type hinting and type casting), its introspective capabilities are quite impressive indeed. Native old functions like “is_int(),” “is_string()” and “is_float()” among others, which have been used for years, gave programmers the ability to check at runtime if the value assigned to a variable honors a specified type.

While it’s fair to say that these and other functions play a relevant role within the introspective facet of the language, the truth is that they fall short and become useless quickly, especially when it comes to analyzing the internal structure of classes and interfaces. Frankly speaking, PHP 4 already included a set of functions that allowed developers to inspect classes at a limited level, and they continue to be widely used in programs today. Unfortunately, with the introduction of a highly-enhanced object model in PHP 5, the limitation imposed by these functions became even more evident.

The happy side of this story is that, along with its most popular object-oriented bells and whistles, PHP 5 was also packaged with a powerful reflection API. This API takes the language’s introspective abilities to a far more mature stage. What’s more, it includes some convenient methods that permit developers to dissect both classes and interfaces down to their bare bones, which can be much more useful than you might think.

As with many other features of PHP 5, unquestionably the best place to get an intimate background in its reflection API is the official documentation. Even so, for many lazy programmers (like me), sometimes it’s good to have at hand an additional guide that quickly shows how to use the most relevant methods of the API in question.

With that idea in mind, in this group of tutorials I’m going to attempt to provide you with a variety of simple code samples that hopefully will get you started using the PHP 5 reflection API — without having to scratch your head trying to figure out how to work with its methods.

Are you ready to start digging deeper into the reflection programming interface provided by PHP 5? Then click on the link below and begin reading the next few lines. It’ll be an instructive experience, trust me!

{mospagebreak title=Building a sample interface and a basic class}

In the introduction, I mentioned the neat capabilities offered by the PHP Reflection API without explaining in detail what it is. So before I move on and start writing any code samples, a more precise explanation is in order here. Basically, this API is comprised of a set of methods that allow you to analyze the inner structure of classes and interfaces very easily, thus making it possible to determine, for example, if a reflected class defines a given method or not, or if the class declares a specified property, in addition to checking whether that property is public, protected or private.

A similar level of reflection can be reached with interfaces as well, but this simple example should give you a clue to all the things that can be achieved with the API. Of course, it’s possible to accomplish much more than determining the visibility of a specific class property. However, as this is a work in progress, I’m going to start covering, for the moment, the API’s basic functionality.

Therefore, to begin showing you the actual power behind the PHP 5’s reflection capabilities, I’m going to define a sample interface along with a basic class, which will be progressively stripped down to their bare bones via pure reflection.

Now that I have explained my plan for this article series, below you’ll find the definitions of the sample interface and its implementing class. They look like this: 

interface Identifier

{

    public function setId($id);

   

    public function getId();

    

}

 

 

/**

* A sample user class

*

* @param  id fname lname email

*/

class User implements Identifier

{

    private $id = NULL;

    private $fname = ‘Alejandro';

    private $lname = ‘Gervasio';

    private $email = ‘alejandro@domain.com';

    const HEADING = ‘Using the Reflection API in PHP 5′;

   

    // constructor (not implemented)

    public function __construct(){}

   

    //setter for id property

    public function setId($id)

    {

        if (!is_numeric($id))

        {

            throw new Exception(‘ID must be a numeric value’);

        }

        $this->id = $id;

    }

   

    // getter for id property

      public function getId()

    {

        return $this->id;

    }

       

    // setter for fname property

    public function setFirstName($fname)

    {

        if (empty($fname) OR !is_string($fname))

        {

            throw new Exception(‘First name must be a non-empty string.’);

        }

        $this->fname = $fname;

    }

   

    // getter for fname property

    public function getFirstName()

    {

        return $this->fname;

    }

   

    // setter for lname property

    public function setLastName($lname)

    {

        if (empty($fname) OR !is_string($fname))

        {

            throw new Exception(‘Last name must be a non-empty string.’);

        }

        $this->lname = $lname; 

    }

   

    // getter for lname property

    public function getLastName()

    {

        return $this->lname;

    }

   

    // setter for email property

    public function setEmail($email)

    {

        if (empty($email) OR !is_string($email) OR strpos($email, ‘@’) === FALSE)

        {

            throw new Exception(‘Email must be a well-formatted email address.’);

        }

        $this->email = $email; 

    }

   

    // getter for email property

    public function getEmail()

    {

        return $this->email;

    }         

}

As you can see above, I defined a trivial interface called “Identifier” along with an implementing “User” class. The interface is so simple that it doesn’t bear any further discussion, so I suggest that you pay attention to the class. It implements not only the unique method declared by the interface, but a few additional ones, which allow you to set and retrieve the values assigned to its $fname, $lname and $email properties.

Logically, in this case the class does nothing particularly useful; it behaves like a simple data container. However, the purpose of coding a class like this is to use it for demonstrating how to dissect its structure via the reflection API.

So far, so good. Now that there’s a basic class and an interface available for immediate testing, the next thing we must do is start coding some examples that show how to put the API to work.

The first of these examples will be coded in the section to come. So click on the link below and keep reading.

{mospagebreak title=Finding the name of a reflected class}

Any decent reflection library should be able to retrieve the most basic information about a target class, and the reflection API provided by PHP is no exception. However, you may be wondering how to use it with the previous interface and its implementing class. Below I’ve coded an example that shows the simplest way to use the API.

Pay close attention to the following code fragment, please:

// create instance of ‘User’ class

$user = new User();

 

 

// create instance of Reflection class and pass in ‘User’ class as argument

$reflector = new ReflectionClass(‘User’);

 

 

// get name of reflected class

echo $reflector->getName(); // displays ‘User’

As you can see above, I first created an instance of the sample “User” class only for demonstrative purposes, and second (here’s where the magic really happens), a new reflector object has been spawned from the native “ReflectionClass” class. This one is truly the workhorse of the entire reflection API; it takes as an as input argument the name of the class that needs to be reflected.

In this example, the string “User” has been passed to the constructor of the “ReflectionClass” class (don’t worry if your tongue gets stuck at this point). This process returns a reflector object that will allow you to retrieve valuable information about the “User” class that you saw in the previous section.

Since I’m just starting to explore the reflection API, the first thing that the above example does is invoke a method called “getName(),” which returns the name of the reflected class. But, wait a minute! We already knew that, right? 

This time, yes, but there will be situations in which the name of the reflected class will not be known ahead of time, so using the “getName()” method is not so pointless as it may seem. Besides, the use of this method opens the door to  working with many others, which will be covered in this tutorial and the ones to come.

At this stage, you’ve learned how to utilize one method of the reflection API to retrieve the name of the class being reflected. That was a fairly straightforward process, so it’s time to explore other methods that will allow us to get additional information about that class. The ones that will be discussed in the following section will return the name of the constant defined within the “User” class, so to learn how to use them, click on the link below and read the new few lines.      

{mospagebreak title=Finding the constants defined by a reflected class}

In the preceding segment, I demonstrated how to use the “getName()” method provided by the native “ReflectionClass” class to obtain the name of the class being reflected. Since this operation was really easy to grasp, I’m now going to show you how to utilize a couple of additional methods to get the names and values of the constants declared by the reflected class.

To do so, in the following lines I coded a brand new script that retrieves the HEADING constant, defined by the previous “User” class: 

// create instance of ‘User’ class

$user = new User();

 

 

// create instance of Reflection class and pass in ‘User’ class as argument

$reflector = new ReflectionClass(‘User’);

 

 

// get constant in reflected class

echo $reflector->getConstant(‘HEADING’); // displays ‘Using the Reflection API in PHP 5′

 

 

// get an array of constants in reflected class

print_r($reflector->getConstants()); // displays Array ( [HEADING] => Using the Reflection API in PHP 5 )

As seen above, retrieving the values assigned  to the constants defined by a given class is only a matter of calling the “getConstant()” and “getConstants()” methods of the reflection API, and nothing else. The first of these methods takes the name of the constant that needs to be parsed, while the second one simply returns an array of constants, populated with their corresponding values. 

This basic code sample does reveal the impressive potential of the reflection API for inspecting the internal structure of a class. But this is only a humble beginning. The API comes packaged with many other handy methods that will be discussed in depth in subsequent tutorials of this series. 

Final thoughts

In this introductory part of the series, I started exploring some of the methods included with the Reflection API bundled with PHP 5. As you saw for yourself, the interface allows you to collect relevant information about a reflected class, including its name, its declared constants and properties, in a extremely straightforward way.

However, I’m only scratching the surface when it comes to the full capabilities that this API freely offers. Therefore, in the next part I’m going to show you how to use it for retrieving additional information about a target class, such as its starting and ending lines, the name of the file that contains the class, the interfaces that it implements and much more.

Don’t miss the upcoming article!

[gp-comments width="770" linklove="off" ]
antalya escort bayan antalya escort bayan