Getting Information on a Reflected Class with the Reflection API

In this second part of a series, I explore some handy methods of the PHP Reflection API. They allow you to retrieve miscellaneous information about a class, including its name and containing file, as well as its starting and ending lines.

Overlooked by many developers, the Reflection API that comes with PHP 5 is a powerful reverse-engineering extension of the language that permits developers to analyze, inspect and retrieve valuable information about selected classes and interfaces by means of a set of convenient methods.

So, if you’re a PHP programmer interested in learning how to put this API to work for you, then this article series might be the material that you’re looking for. In its tutorials you’ll be provided with a decent number of code samples aimed at demonstrating how to use the most relevant reflective methods included with the API.

And now that you’ve been introduced to the goal of the series, it’s time to review the topics that were discussed in the first installment, taking into account the possibility that you haven’t read it yet. So, to put it simply, in that article I coded a couple of scripts that showed how to obtain the name of a reflected class and the values assigned to its unique constant via the “getName(),” getConstant()” and “getConstants()” reflection methods.

Despite their simplicity, these introductory examples demonstrated the remarkable introspective capabilities offered by the reflection API when used in an object-oriented environment. However, as you might have guessed, the API comes bundled with many other methods that deserve a close analysis as well.

With that premise in mind, in this second episode of the series I’m going to show you how to get miscellaneous information about a reflected class, including things like its starting and ending lines within its containing file, the interfaces that the class implements, and so forth.

Now, let’s leave the preliminaries behind us and continue to explore a few more handy methods provided by the PHP 5 reflection API. Let’s get going!

{mospagebreak title=Review: using the PHP 5 reflection API}

As usual, before I proceed to demonstrate how to use other useful methods included with the PHP reflection API, it’d be convenient to take a quick look at the code samples developed in the previous article.

In that part of the series I showed how to get the name and the values assigned to the constant declared by a sample class. The class in question was a really basic one, and implemented an interface called “Identifier.”

The definitions of this interface and the implementing class are shown below:

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;

    }         

}

From the above code fragment, it’s clear to see that the purpose of coding the “Identifier” interface and its implementing “User” class is only to have two sample structures that can be easily analyzed internally via reflection.

Things start to look more interesting, though, when these example entities are reverse-engineered through some reflective methods. The following code snippet shows how to get the name of a reflected class and information about the constants that it declares in a few simple steps:

// 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’

// 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 )

See how easy it is to collect information on a selected class via the reflection API? I guess you do! In this case, the information retrieved is somewhat trivial, but it demonstrates how powerful the API can be for stripping classes and interfaces down to their bare bones by means of an object-oriented approach.

Of course, if you’re like me, you’ll typically want to know more about a class or interface, aside from retrieving its name and its declared constants. Fortunately, the reflection API provides some other methods that allow you to fetch mixed class information in a simple manner.

In the following section I’m going to teach you how to retrieve the set of default properties declared by the earlier “User” class, along with the data embedded into its doc block.

To learn more about how this will be done, click on the link below and read the segment to come.

{mospagebreak title=The getDefaultProperties() and getDocComment() reflection methods}

As you learned in the previous section, once a reflector object has been tied to a specific class, it’s very easy to collect information about its internal structure. So far, I’ve showed how to use reflection to get the name of a class, along with its constants, but it’s possible to find out much more about it.

To demonstrate this, below I wrote a simple script that shows how to get the default properties declared by the “User” class, along with the data included within its doc block. The script that does that looks like this: 

// 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 default properties in reflected class

print_r($reflector->getDefaultProperties()); // displays Array ( [id] => [fname] => Alejandro [lname] => Gervasio [email] => alejandro@domain.com )

// get doc comments in reflected class

print_r($reflector->getDocComment()); // displays /** * A sample user class * * @param id fname lname email */

That was really easy to achieve, wasn’t it? By calling the new “getDefaultProperties()” and “getDocComment()” methods, it’s feasible to get the default properties declared by the “User” class along with the information embedded in its document block. As you can see, both methods return data in the form of arrays, which can be easily dumped to the browser or eventually stored in variables for further processing.

Now that you’ve learned how to use a couple of additional methods provided by the reflection API, it’s time to explore a few others. However, before I do that, I’d like to stress one important thing with reference to the previous example: while “getDefaultProperties()” does a decent job returning the set of default properties declared by a reflected class, in many situations it’s desirable to know their level of visibility as well.

Does this mean that the reflection API isn’t capable of doing such a thing? Fear not; it can do this by using a specialized class called “ReflectionProperty,” which will be properly analyzed in a future article. For the moment though, be patient and read the following section. In it I’m going to discuss how to use the API for collecting information about the physical location of the “User” class inside the file system.

Now, click on the link below and keep reading, please. 

{mospagebreak title=The getStartLine(), getEndLine() and getFileName() methods}

Not surprisingly, the reflection API has the ability to get information about a class that has to do specifically with its location in the file system. For instance, it’s possible to know exactly where the definition of the class begins and ends within its containing file and the name of the file in question.

To clarify this concept, pay attention to the following code sample, which performs these tasks by using three new reflective methods: 

 

// 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 starting line number of reflected class

echo $reflector->getStartLine(); // displays ’15’

// get ending line number of reflected class

echo $reflector->getEndLine(); // displays ’87’

// get filename of reflected class

echo $reflector->getFileName(); // displays ‘C:pathtoreflection_apireflection_api.php’ 

Definitely, the starting and ending lines of a class within a file aren’t the most useful things to know, but the “getStartLine()” and “getEndLine()” methods make this process a no-brainer. On the other hand, the “getFileName()” does good work returning the name of the file that included the reflected class.

And if all of these introspection capabilities still don’t convince you to use the reflection API, below is an example that shows how to use a reflector object to get the name of the interface implemented by the sample “User” class:  

// get name of implemented interfaces

print_r($reflector->getInterfaceNames()); // displays Array ( [0] => Identifier ) 

// get associative array of implemented interfaces

print_r($reflector->getInterfaces()); // displays Array ( [0] => Identifier ) Array ( [Identifier] => ReflectionClass Object ( [name] => Identifier ) )

There you have it. By using only two methods, it’s possible to determine what interfaces are implemented by a reflected class. Considering that “getInterfaces()” returns a new ReflectionClass object, it’s easy to iterate over all of the interfaces implemented by a class in the following way:

$reflector = new ReflectionClass(‘User’);

foreach ($reflector->getInterfaces() as $interface)

{

    echo $interface->getName() . ‘<br />';

}

And with this final example, we’ve come to the end of this second chapter of the series. As always, feel free to edit all of the code samples shown in this tutorial, a process that surely will give you a more intimate knowledge of reflection in PHP 5.

Final thoughts

In this second episode of the series, I explored a few handy methods packaged with the PHP reflection API, which allowed you to retrieve miscellaneous information about a class, including its name and containing file, as well as its starting and ending lines.

In addition, the use of the “getInterfaceNames()” and “getInterfaces()” methods permitted us to inspect the interfaces implemented by a class. This can be useful in situations where client code needs to know if an object honors a determined interface contract.

In the upcoming tutorial, things will become even more interesting. I’m going to discuss other helpful methods, which will be used to obtain all sorts of rich information about the methods defined by a reflected class.

My suggestion is simple: don’t miss the next part!

[gp-comments width="770" linklove="off" ]

antalya escort bayan antalya escort bayan Antalya escort diyarbakir escort