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

Posted

技术标签:

【中文标题】php - 检查存储在字符串中的类名是不是正在实现接口【英文标题】: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(实现ProgrammerStudents\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 说他们不想实例化这个类。 【参考方案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)) 
    // ...

【讨论】:

以上是关于php - 检查存储在字符串中的类名是不是正在实现接口的主要内容,如果未能解决你的问题,请参考以下文章

PHP如何检查一个数组内是不是存在指定元素

PHP如何检查一个数组内是不是存在指定元素

PHP中的类名

检查 Azure Blob 存储中是不是存在 blob (php)

如何检查 DOM 中所有 div 的类名是不是具有带有 vanilla Javascript 的特定字符串?

检查字符串是不是只包含 PHP 中的 URL