有没有办法定义一个类,以便只有在其他类可用时才扩展另一个类?
答案 0 :(得分:8)
没有任何东西可以让你做
class Foo extendsIfExist Bar
但是你可以用runkit的
来表现PHP手册中的示例:
class myParent {
function parentFunc() {
echo "Parent Function Output\n";
}
}
class myChild {
}
runkit_class_adopt('myChild','myParent');
myChild::parentFunc();
可以从PECL获得runkit扩展。但是,不鼓励使用因为需要它几乎总是一个有缺陷设计的指标。
免责声明:我只假设以下示例之类的内容是您提出问题的原因。如果不是,请忽略那部分答案。
如果您在运行时有条件地需要某些功能,请考虑聚合您要扩展的类,例如:尝试一下
的内容interface Loggable
{
public function log($message);
}
class Foo implements Loggable
{
protected $logger;
public function setLogger($logger)
{
$this->logger = $logger;
}
public function log($message)
{
if($this->logger !== NULL) {
return $this->logger->log($message);
}
}
}
在上面的示例中,我们想要的功能是log()
。因此,我们不是检测记录器类是否可用,然后将此功能伪装到我们的Foo类中,而是通过添加接口Loggable来告诉它需要此功能。如果存在Logger类,我们在Foo中实例化并聚合它。如果它不存在,我们仍然可以调用日志,但它不会做任何事情。这更加solid。
答案 1 :(得分:4)
我是这样做的。
if (class_exists('parentClass') {
class _myClass extends parentClass {}
} else {
class _myClass {}
}
class myClass extends _myClass
{
...
}
答案 2 :(得分:2)
这是Pekka回答的答案和扩展。
首先在Pekka,我认为eval是完全错误的,
有什么问题if(class_exists("bar"))
{
class foo extends bar
{
}
}
这也是我的答案。
答案 3 :(得分:2)
最近遇到类似的要求,我的库中的类需要从ClassB动态扩展(如果存在),否则从A类扩展。
我的解决方案(我的代码是命名空间,无论如何都适用相同的概念):
namespace someNamespace;
spl_autoload_register(function($class) {
if (strcasecmp($class, 'someNamespace\SomeFakeClass') === 0) {
if (class_exists('ClassB',false)) {
class_alias('ClassB', 'someNamespace\SomeFakeClass');
} else {
class_alias('ClassA', 'someNamespace\SomeFakeClass');
}
}
}, true, true);
/** @noinspection PhpUndefinedClassInspection */
/** @noinspection PhpUndefinedNamespaceInspection */
class MyClass extends \someNamespace\SomeFakeClass {
# ... real logic here ...
}
使用上述解决方案, MyClass 类将动态继承 ClassB (如果存在),否则它继承自 ClassA 。
此解决方案避免使用 eval ,这对我来说是一个很大的优势。
希望这有帮助。
编辑:请注意,@ notinspection符号存在,以便PHPStorm等IDE不会报告有关不存在的类的错误。
答案 4 :(得分:1)
你是说这个吗?
<?php
class Foo{
}
if( class_exists('Foo') ){
class SubFoo extends Foo{
}
}
if( class_exists('Bar') ){
class SubBar extends Bar{
}
}
$a = new SubFoo; // OK
$b = new SubBar; // Fatal error: Class 'SubBar' not found