Reflecting Abstract Classes and Interface Implementers with the Reflection API

In this sixth part of a seven-part series, I explain how to use the power of reflection to find out if a class has been defined abstract and final, and if it implements a specified interface. Performing all of these tasks is a straightforward process, so you shouldn’t have major problems using these reflection methods within your own PHP applications.

When it comes to highlighting the most remarkable features incorporated into PHP 5 a few years ago, undoubtedly its enhanced object model, along with the support for native exceptions and interfaces, are the first things that come to mind. However, as you may have heard, the language also comes with a powerful library commonly known as the Reflection API, which allows developers to perform all sorts of reverse engineering tasks on both classes and interfaces. This process can be far more useful that you might think.

Nowadays, many of the methods included with the reflection API are used widely in well-established frameworks and third-party libraries. This has contributed to the spread of the API’s popularity among developers. It is possible, however, that you still haven’t had the opportunity to take advantage of the functionality given by reflection within your own object-oriented applications, or simply don’t know how to use this API in a really useful manner.

If that’s the case, in this group of tutorials you’ll find a decent number of code samples that will show you how to utilize some of the most important methods bundled with the reflection API. They will let you obtain relevant information about your classes and interfaces with only minor effort.

And speaking of relevant information on classes and interfaces, in the previous chapter of the series I discussed how to use the “hasProperty()” and “getStaticProperties()” reflection methods with a sample class. The first of these methods made it possible to know if a specific property was declared by the particular class, and the second one allowed you (at least in theory) to retrieve all of the class’s static properties in one go.

As I said before, the reflection API can be used for inspecting classes in many different ways. In the lines to come, in fact, I’m going to demonstrate how to employ it to determine if a specified class is concrete or abstract, and if it implements a particular interface. That sounds pretty interesting, right?

Now, it’s time to explore a few more handy methods packaged with the PHP reflection API. Let’s go!

{mospagebreak title=Review: the hasProperty() and getStaticProperties() reflection methods}

In the previous article, as I mentioned, I explained how to use the “hasProperty()” and “getStaticProperties()” reflection methods with a sample class. Below I reintroduced the source code corresponding to these examples, starting with the definitions of the class itself and its associated interface. Here they are:

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;

    }         

}

Since the “Identifier” interface and its implementing “User” class have been coded only for demonstration purposes, explaining how they function (again) would be a waste of time. Instead, you should look at the following code fragment, which shows how to use the aforementioned “hasProperty()” and “getStaticProperties()” methods, first for checking the existence of a specific property, and then for getting all of the static properties defined by this class:

// create instance of ‘User’ class

$user = new User();

 

 

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

 

 

$reflector = new ReflectionClass(‘User’);

 

 

// check if the reflected class has a specified property

if ($reflector->hasProperty(‘lname’))

{

    echo ‘Property found in reflected class’; // displays ‘Property found in reflected class’

}

else

{

    echo ‘Property not found in reflected class’;

}

 

 

// get static properties of reflected class

print_r($reflector->getStaticProperties()); // displays nothing

Undeniably, getting information about the properties of a class is a no-brainer process, thanks to the numerous methods included with the reflection API. Again, it’s fair to stress here that the API offers many other handy methods that will let you analyze your classes and interfaces down to their bare bones, so if you need to perform a particular introspection task that hasn’t been covered in this series, make sure to check the API’s official online documentation.

So far, so good. At this stage, you’ve learned how to obtain relevant data about the properties of a class, so now I’m going to discuss using reflection to know if a class has been declared abstract and final.

These subjects will be covered in the section to come. To get there, simply click on the link below and read the next few lines.     

{mospagebreak title=Determining if a class is abstract, final and an interface implementer}

As with the other reflection processes covered in this and previous tutorials of the series, checking if a class has been defined abstract and final (or both) is just a matter of calling the proper reflective method and nothing else. It’s that easy, really.

However, if you’re anything like me, you want to see a practical example that shows how to accomplish these tasks. Below I coded a simple script that verifies not only if the earlier “User” class is abstract and final, but checks to see if it’s an implementer of the “Identifier” interface, which in this case turns out to be true.

Here’s the script in question:

// create instance of ‘User’ class

$user = new User();

 

 

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

 

 

$reflector = new ReflectionClass(‘User’);

 

 

// check if the reflected class is abstract

if ($reflector->isAbstract())

{

    echo ‘Reflected class is abstract’; // displays ‘Reflected class is not abstract’

}

else

{

    echo ‘Reflected class is not abstract’;

}

 

 

// check if the reflected class is final

if ($reflector->isFinal())

{

    echo ‘Reflected class is final’; // displays ‘Reflected class is not final’

}

else

{

    echo ‘Reflected class is not final’;

}

 

 

// check if the reflected class is an implementer of a specified interface

if ($reflector->implementsInterface(‘Identifier’))

{

    echo ‘Reflected class is an implementer of the specified interface’; // displays ‘Reflected class is an implementer of the specified interface’

}

else

{

    echo ‘class is not an implementer of the specified interface’;

}

Definitely, the above script speaks for itself, as it invokes three brand new reflection methods called “isAbstract(),” “isFinal()” and “implementsInterface()” respectively, to check if the “User” class is abstract and final, and also if it implements the “Identifier” interface.

To be frank, understanding the underlying logic of these methods is far from rocket science, so it’s time to explore other handy methods offered by the reflection API. Therefore, in the following segment I’m going to discuss the use of the “isInstantiable()” method, which as its name suggests, allows you to know if a class can be instantiated.

This topic will be the conclusion of this sixth installment of the series, so please click on the link that appears below and read the lines to come.   

{mospagebreak title=Checking if a class can be instantiated}

As I promised in the section that you just read, I’d like to finish this tutorial by showing you how to use reflection for verifying whether or not a specified class can be instantiated from client code. To achieve this, the reflection API provides the handy “isInstantiable()” method, which can be used in the following way:

// create instance of ‘User’ class

$user = new User();

 

 

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

 

 

$reflector = new ReflectionClass(‘User’);

 

 

// check if the reflected class can be instantiated

if ($reflector->isInstantiable())

{

    echo ‘Reflected class is instantiable’; // displays ‘Reflected class is instantiable’

}

else

{

    echo ‘Reflected class is not instantiable’;

}

Since the sample “User” class can indeed be instantiated, in the above checking block the “isInstantiable()” method will return a value of TRUE. Nonetheless, if you use it with an abstract class or with one that declares its constructor protected or private, the method will return FALSE.

While checking if it’s possible to create instances of a class seems to be at first sight a rather pointless task, this is far from being true. This reflection process is often found in frameworks that implement some sort of dispatcher mechanism, and in some dependency injection containers as well. So, if you need to inspect classes an runtime with an acceptable level of automation, the methods offered by the reflection API are definitely an option worth looking at.

Final thoughts

In this sixth part of the series, I illustrated with some easy-to-grasp code samples how to use the power of reflection to know if a class has been defined abstract and final, and if it implements a specified interface. As you saw for yourself, performing all of these tasks was a straightforward process, meaning that you shouldn’t have major problems using the previous reflection methods within your own PHP applications.

In the last episode, the focus will be on how to take advantage of reflection to verify whether a class is native or user-defined.

Don’t miss the final article!

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