Dynamically subclass

I am using Kohana and just found this piece of code in my autoload method

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

      

basically what it does, when I mean a class that doesn't exist (by creating an object, calling class_exists (), etc.) Kohana will create a class (like Foo) that extends the library class which follows a specific naming convention (like Foo_Core). just curious if there is a way to do something like this, but without using eval?

+1


source to share


3 answers


If you want to create a dynamic class then eval()

this is a goto function (intended for puns). However, however related, I found that you can put a class declaration in a statement if-then

. So you can do the following:

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

      



I use this to check if dynamically generated classes are leaking (from config file) ... if so load the class, otherwise ... restore the class and load a new one. So if you want to create dynamic classes for the same reasons, this might be the solution.

+2


source


I think you are stuck with eval()

for this.

It is labeled as a "disgusting hack", so it does it fine :)



I would be interested to know what you are doing with such an empty class ...

+1


source


If you want to be able to cache your dynamically generated classes, you can write it to a file and require it. This can be considered equivalent, but this is an option. For classes that are created once and are used frequently, this might be a good solution. For classes that need to be dynamic every time, sticking with eval is probably the best solution.

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

      

In this example, the idea is that you are creating dynamic proxies for the class $object

. $this->generateProxy($object)

will return a string that looks something like what it looks like $extension

in the original question.

This is far from a complete implementation, just some pseudo code to show what I am describing.

0


source







All Articles