phpoopnamespaces

php - check if class name stored in a string is implementing an interface


I understand that my question is somehow wrong, but I'm still trying to solve this problem.

I have an interface Programmer:

interface Programmer {
    public function writeCode();
}

and a couple of namespaced classes:

I have this class names stored in array $students = array("BjarneProgrammer", "CharlieActor");

I want to write a function, that will return an instance of class if it's implementing Programmer interface.

Examples:

getStudentObject($students[0]); - It should return an instance of BjarneProgrammer because it's implementing Programmer.

getStudentObject($students[1]); - It should return false because Charlie is not a Programmer.

I tried it using instanceof operator, but the main problem is that I do not want to instantiate an object if it's not implementing Programmer.

I checked How to load php code dynamically and check if classes implement interface, but there is no appropriate answer as I don't want to create object unless it's returned by function.


Solution

  • You can use class_implements (requires PHP 5.1.0)

    interface MyInterface { }
    class MyClass implements MyInterface { }
    
    $interfaces = class_implements('MyClass');
    if($interfaces && in_array('MyInterface', $interfaces)) {
        // Class MyClass implements interface MyInterface
    }
    

    You can pass the class name as a string as function's argument. Also, you may use Reflection

    $class = new ReflectionClass('MyClass');
    if ( $class->implementsInterface('MyInterface') ) {
        // Class MyClass implements interface MyInterface
    }
    

    Update : (You may try something like this)

    interface Programmer {
        public function writeCode();
    }
    
    interface Actor {
        // ...
    }
    
    class BjarneProgrammer implements Programmer {
        public function writeCode()
        {
            echo 'Implemented writeCode method from Programmer Interface!';
        }
    }
    

    Function that checks and returns instanse/false

    function getStudentObject($cls)
    {
        $class = new ReflectionClass($cls);
        if ( $class->implementsInterface('Programmer') ) {
            return new $cls;
        }
        return false;
    }
    

    Get an instance or false

    $students = array("BjarneProgrammer", "CharlieActor");
    $c = getStudentObject($students[0]);
    if($c) {
        $c->writeCode();
    }
    

    Update: Since PHP - 5.3.9+ you may use is_a, example taken from PHP Manual:

    interface Test {
        public function a();
    }
    
    class TestImplementor implements Test {
        public function a() {
            print "A";
        }
    }
    
    $testImpl = new TestImplementor();
    
    var_dump(is_a($testImpl, 'Test')); // true
    

    Working example here.