php - 检查存储在字符串中的类名是否正在实现接口

时间:2013-11-24 00:50:26

标签: php oop namespaces

我知道我的问题有些不对劲,但我仍在尝试解决这个问题。

我有一个界面Programmer

interface Programmer {
    public function writeCode();
}

以及一些命名空间类:

  • Students\BjarneProgrammer(实施Programmer
  • Students\CharlieActor(实施Actor

我将这个类名存储在数组$students = array("BjarneProgrammer", "CharlieActor");

我想编写一个函数,如果它正在实现Programmer接口,它将返回一个类的实例。

示例:

getStudentObject($students[0]); - 它应该返回BjarneProgrammer的实例,因为它正在实现程序员。

getStudentObject($students[1]); - 它应该返回false,因为查理不是程序员。

我使用instanceof运算符尝试了它,但主要问题是我想要实例化一个对象,如果它没有实现Programmer。

我检查了How to load php code dynamically and check if classes implement interface,但没有合适的答案,因为我不想创建对象,除非它是由函数返回的。

3 个答案:

答案 0 :(得分:16)

您可以使用class_implements(需要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
}

您可以将class name作为字符串作为函数的参数传递。此外,您可以使用Reflection

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

更新:(您可以尝试这样的事情)

interface Programmer {
    public function writeCode();
}

interface Actor {
    // ...
}

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

检查并返回instanse/false

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

获取实例或错误

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

答案 1 :(得分:13)

如果您使用的是现代版本的PHP(5.3.9 +),那么最简单(也是最好)的方法是将is_a()与第三个参数true一起使用:

$a = "Stdclass";

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

这两个都会返回true。

答案 2 :(得分:0)

使用 PHP 的函数 is_subclass_of()

use App\MyClass;
use App\MyInterface;

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