我正在使用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?
答案 0 :(得分:2)
如果你想创建一个动态类,那么eval()
是goto函数(双关语。)但是有点相关,我发现你可以发表一个类声明在if-then
声明中。所以你可以做到以下几点:
if(true)
{
class foo
{
// methods
}
}
我用它来检查动态创建的类(来自配置文件)是否是最新的...如果是,则加载类,否则......重新生成类,并加载新类。因此,如果您希望出于类似的原因创建动态类,这可能是一种解决方案。
答案 1 :(得分:1)
答案 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
看起来差不多的字符串。
这绝不是一个完整的实现,只是一些伪代码来展示我所描述的内容。