动态创建子类

时间:2009-01-08 09:27:27

标签: php class oop

我正在使用Kohana并在自动加载方法中找到了这段代码

        // Class extension to be evaluated
        $extension = 'class '.$class.' extends '.$class.'_Core { }';

        // Start class analysis
        $core = new ReflectionClass($class.'_Core');

        if ($core->isAbstract())
        {
            // Make the extension abstract
            $extension = 'abstract '.$extension;
        }

        // Transparent class extensions are handled using eval. This is
        // a disgusting hack, but it gets the job done.
        eval($extension);

基本上它的作用是当我指的是一个不存在的类时(通过对象实例化,调用class_exists()等),Kohana将创建一个类(例如.Foo),它扩展了一个跟随的库类某些命名约定(例如Foo_Core)。只是好奇,有没有办法做类似但没有使用eval?

3 个答案:

答案 0 :(得分:2)

如果你想创建一个动态类,那么eval()是goto函数(双关语。)但是有点相关,我发现你可以发表一个类声明在if-then声明中。所以你可以做到以下几点:

if(true)
{
    class foo
    {
       // methods
    }
}

我用它来检查动态创建的类(来自配置文件)是否是最新的...如果是,则加载类,否则......重新生成类,并加载新类。因此,如果您希望出于类似的原因创建动态类,这可能是一种解决方案。

答案 1 :(得分:1)

我认为你坚持使用eval()

它被标记为“令人厌恶的黑客”,所以这样就可以了:)

我有兴趣知道你对这样一个空洞的课程做了什么......

答案 2 :(得分:0)

如果您希望能够缓存动态创建的类,则可以写出文件并要求它。这可以被认为是同样的hack-ish,但它是一种选择。对于一次创建并经常使用的类,它可能是一个很好的解决方案。对于每次都需要动态的类,坚持使用eval可能是最好的解决方案。

$proxyClassOnDisk = '/path/to/proxyCodeCache/' . $clazz .'.cachedProxyClass';
if ( ! file_exists($proxyClassOnDisk) ) {
    // Generate the proxy and put it into the proxy class on disk.
    file_put_contents($proxyClassOnDisk, $this->generateProxy($object));
}
require_once($proxyClassOnDisk);

在此示例中,您的想法是为$object类创建动态代理。 $this->generateProxy($object)会返回与原始问题中$extension看起来差不多的字符串。

这绝不是一个完整的实现,只是一些伪代码来展示我所描述的内容。