36

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:

  • Students\BjarneProgrammer (implements Programmer)
  • Students\CharlieActor (implements Actor)

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.

1
  • @how: The OP says they don't want to instantiate the class. Commented Nov 18, 2015 at 23:06

3 Answers 3

37

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, your answer helped me. I used just ReflectionClass - codepad.org/EvZRbaWZ
I'm using method from ReflectionClass return $class->newInstance(); instead of return new $cls;. Thanks again :>
That's fine I think :-)
27

If you're using a modern version of PHP (5.3.9+), then the easiest (and best) way would be to use is_a() with the third parameter true:

$a = "Stdclass";

var_dump(is_a($a, "stdclass", true));
var_dump(is_a($a, $a, true));

Both of those will return true.

2 Comments

PHP documentation is kind of misleading (if you don't care to read every sentence :) ) - it says first parameter of is_a is an object. But if you read on - you find out it can actually be a string...
For me, this was the more elegant solution
10

Use PHP's function is_subclass_of():

use App\MyClass;
use App\MyInterface;

if (is_subclass_of(MyClass::class, MyInterface::class)) {
    // ...
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.