强制动态加载的类来扩展或实现接口

时间:2022-09-23 17:35:32

Anyone know if it's possible in PHP to force a class to extend or implement an interface without the child class having to declare it?

任何人都知道在PHP中是否有可能强制类扩展或实现接口而子类不必声明它?

Example:

interface Requirements
{
    public function __construct();
    public function kittens();
}

class DingleBerry
{
    public function __construct()
    {
        // yadda yadda yadda    
    }
}

// Example of my initial hope
// of what you could do

$kittens = new DingleBerry implements Requirements;

Obviously that doesn't work, but I need a way of loading in classes that have no predetermined knowledge of the interface requirements but are forced to abide by them.

显然这不起作用,但我需要一种在没有预先了解接口要求但却*遵守它们的类中加载的方法。

My overall goal is to check to see if the class implements the Requirements BEFORE its loaded and it's constructor is called.

我的总体目标是检查类是否在加载之前实现了需求,并且调用了它的构造函数。

So I CANNOT use this:

所以我不能用这个:

interface Requirements
{
    public function __construct();
    public function kittens();
}

class DingleBerry
{
    public function __construct()
    {
        // DO BAD STUFF (i.e. eat your soul)
    }
}

// Example of what I CANNOT
// do.

$kittens = new DingleBerry;

if( !($kittens instanceof Requirements) )
{
    // eat pizza.    
}

Because then DingleBerry's constructor is called before I can check if it implements the Requirements. Dig?

因为在我检查它是否实现了要求之前调用了DingleBerry的构造函数。挖?

2 个解决方案

#1


2  

You cannot modify an already declared class or interface definition without using a third-party extension (e.g.: runkit).

如果不使用第三方扩展(例如:runkit),则无法修改已声明的类或接口定义。

Runkit has a runkit_class_adopt function that may fulfil that need. Unfortunately I can't test it because the PECL version won't compile on my machine.

Runkit有一个runkit_class_adopt函数可以满足这个需求。不幸的是我无法测试它,因为PECL版本无法在我的机器上编译。

For the first part of your question, you can check if a class implements a given interface without instantiating it, and without the Reflection API:

对于问题的第一部分,您可以检查一个类是否实现了给定的接口而没有实例化它,并且没有Reflection API:

// checks if class Bar implements Foo
if (in_array('Foo', class_implements('Bar'))) {
    $foo = new Bar;
} else {
    throw new Exception('Interface not implemented');
}

#2


1  

Untested but theoretically this is the API:

未经测试但理论上这是API:

<?php
$reflection = new ReflectionClass('DingleBerry');
$reflection->implementsInterface('Requirements');
?>

http://php.net/manual/en/book.reflection.php
http://mark-story.com/posts/view/using-the-php-reflection-api-for-fun-and-profit

#1


2  

You cannot modify an already declared class or interface definition without using a third-party extension (e.g.: runkit).

如果不使用第三方扩展(例如:runkit),则无法修改已声明的类或接口定义。

Runkit has a runkit_class_adopt function that may fulfil that need. Unfortunately I can't test it because the PECL version won't compile on my machine.

Runkit有一个runkit_class_adopt函数可以满足这个需求。不幸的是我无法测试它,因为PECL版本无法在我的机器上编译。

For the first part of your question, you can check if a class implements a given interface without instantiating it, and without the Reflection API:

对于问题的第一部分,您可以检查一个类是否实现了给定的接口而没有实例化它,并且没有Reflection API:

// checks if class Bar implements Foo
if (in_array('Foo', class_implements('Bar'))) {
    $foo = new Bar;
} else {
    throw new Exception('Interface not implemented');
}

#2


1  

Untested but theoretically this is the API:

未经测试但理论上这是API:

<?php
$reflection = new ReflectionClass('DingleBerry');
$reflection->implementsInterface('Requirements');
?>

http://php.net/manual/en/book.reflection.php
http://mark-story.com/posts/view/using-the-php-reflection-api-for-fun-and-profit