2011-01-13 129 views
5

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

+4

从体系结构的角度来看,这并没有多大意义 - 无论是需要扩展一个类还是不需要。你想达到什么目的? (可能有一个更简单的方法。) – 2011-01-13 15:51:58

+4

应该没有理由动态创建类,你应该有一个永远不需要这样的事情的可靠系统。除非如上所述,否则可能会有一个更简单的方法来实现您的目标。 – RobertPitt 2011-01-13 15:57:46

+0

RobertPitt是100%正确的。我会重新思考这个问题,因为这听起来像是应该首先研究的结构中存在较大的错误。 – 2011-01-13 15:59:22

回答

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(); 

runkit扩展可从PECL获得。但是,它的使用是不鼓励的,因为需要它几乎总是一个有缺陷的设计指标。


免责声明:我只是假设像下面的例子就是为什么你问你的问题的原因。如果不是这样,不考虑那部分答案。

如果您需要在运行时有条件地使用某些功能,请考虑将要扩展的类(例如,尝试沿着

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

你的意思是?

<?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 
2

这是Pekka答案的答案和延伸。

首先在佩卡,我觉得EVAL是完全错误的,什么是错的

if(class_exists("bar")) 
{ 
    class foo extends bar 
    { 

    } 
} 

,这也是我的答案以及。

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,这对我来说是一个很大的优势。

希望这会有所帮助。

编辑:请注意,存在@noinspection表示法,所以IDE(如PHPStorm)不会报告有关不存在的类的错误。

4

我是这样做的。

if (class_exists('parentClass') { 
    class _myClass extends parentClass {} 
} else { 
    class _myClass {} 
} 
class myClass extends _myClass 
{ 
... 
}