Я использую 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?






Если вы хотели иметь возможность кэшировать свои динамически созданные классы, вы могли бы записать в файл и потребовать его вместо этого. Это можно было бы также считать хакерским, но это вариант. Для классов, которые создаются один раз и часто используются, это может быть хорошим решением. Для классов, которые должны быть динамическими каждый раз, использование 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 выглядит в исходном вопросе.
Это ни в коем случае не полная реализация, это просто псевдокод, показывающий то, что я описываю.
Если вы хотите создать динамический класс, то eval() - это функция goto (каламбур предназначен.). Как бы то ни было, я обнаружил, что вы можете поместить объявление класса в оператор if-then. Итак, вы можете сделать следующее:
if (true)
{
class foo
{
// methods
}
}
Я использую это, чтобы проверить, являются ли динамически созданные классы (из файла конфигурации) текущими ... если да, то загрузите класс, в противном случае ... регенерируйте класс и загрузите новый. Поэтому, если вы хотите создать динамические классы по аналогичным причинам, это может быть решением.