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

Sti*_*oza 15 php oop namespaces

我明白我的问题有些不对劲,但我仍在努力解决这个问题.

我有一个界面Programmer:

interface Programmer {
    public function writeCode();
}
Run Code Online (Sandbox Code Playgroud)

以及一些命名空间类:

  • Students\BjarneProgrammer(工具Programmer)
  • Students\CharlieActor(工具Actor)

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

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

例子:

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

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

我试了一下使用instanceof运营商,但主要的问题是,我希望,如果它不执行编程实例化一个对象.

我检查了如何动态加载PHP代码并检查类是否实现接口,但是没有合适的答案,因为我不想创建对象,除非它是由函数返回的.

The*_*pha 19

你可以使用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
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

interface Programmer {
    public function writeCode();
}

interface Actor {
    // ...
}

class BjarneProgrammer implements Programmer {
    public function writeCode()
    {
        echo 'Implemented writeCode method from Programmer Interface!';
    }
}
Run Code Online (Sandbox Code Playgroud)

检查和返回的功能 instanse/false

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

获取实例或错误

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


irc*_*ell 15

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

$a = "Stdclass";

var_dump(is_a($a, "stdclass", true));
var_dump(is_a($a, $a, true));
Run Code Online (Sandbox Code Playgroud)

这两个都将返回真实.

  • PHP文档有点误导(如果您不愿意阅读每个句子:))-它说is_a的第一个参数是一个对象。但是,如果您继续阅读-您发现它实际上可以是一个字符串... (2认同)

Mic*_*fer 7

使用 PHP 的函数is_subclass_of()

use App\MyClass;
use App\MyInterface;

if (is_subclass_of(MyClass::class, MyInterface::class)) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)