【问题标题】:php - check if class name stored in a string is implementing an interfacephp - 检查存储在字符串中的类名是否正在实现接口
【发布时间】:2013-12-08 19:20:13
【问题描述】:

我知道我的问题在某种程度上是错误的,但我仍在努力解决这个问题。

我有一个接口Programmer

interface Programmer {
    public function writeCode();
}

还有几个命名空间类:

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

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

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

示例:

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

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

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

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

【问题讨论】:

  • @how:OP 说他们不想实例化这个类。

标签: php oop namespaces


【解决方案1】:

您可以使用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;
}

获取实例或false

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

【讨论】:

  • 谢谢,您的回答帮助了我。我只使用了 ReflectionClass - codepad.org/EvZRbaWZ
  • 我正在使用 ReflectionClass return $class->newInstance(); 中的方法,而不是 return new $cls;。再次感谢:>
  • 我认为这很好:-)
【解决方案2】:

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

$a = "Stdclass";

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

这两个都将返回 true。

【讨论】:

  • PHP 文档有点误导(如果您不想阅读每个句子:))- 它说 is_a 的第一个参数是一个对象。但是如果你继续阅读 - 你会发现它实际上可以是一个字符串......
【解决方案3】:

使用PHP的函数is_subclass_of():

use App\MyClass;
use App\MyInterface;

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

【讨论】:

    猜你喜欢
    • 2016-10-13
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 2016-09-29
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    相关资源
    最近更新 更多