动态类扩展

时间:2011-01-13 15:49:02

标签: php oop

有没有办法定义一个类,以便只有在其他类可用时才扩展另一个类?

5 个答案:

答案 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