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