Определить класс динамически? - PullRequest
2 голосов
/ 16 марта 2010

Есть ли способ динамически и условно создать определение класса в PHP, т.е.

if (condition matches)
  include file containing class definition
else
  class myclass extends ancestor_class { .................... }

без eval()?

Мой фон - принятый ответ на этот вопрос . Я ищу лучший способ создать неприкасаемую базовую библиотеку с пользовательскими пустыми классами, расширяющими базовую библиотеку, если это необходимо.

Я хочу создать окончательное определение класса «на лету», если для определенного класса-предка не существует определенного пользователем пустого класса.

О включении другого файла включения (содержащего пустое определение класса) не может быть и речи, поскольку будет довольно много классов.

Обновление: Это представляется возможным в блоке нормальных условий - об этом не думали. Однако, согласно этой статье , она также считается плохой практикой и может быть удалена в будущем. Хм. Творческие идеи приветствуются.

1 Ответ

2 голосов
/ 16 марта 2010

См. Комментарии к вопросу для получения дополнительной информации - я постараюсь обобщить, поскольку это может быть полезно для других: -)


Прежде всего, я полагаю, что цель состоит в том, чтобы пользователи сами не создавали почти пустые файлы - я помню еще один вопрос, я думаю, он был от вас, откуда это всплыло.

Если так, то почему бы просто не создать эти почти пустые файлы динамически?
Я имею в виду, что-то вроде этого:

if (condition matches) {
    include file containing class definition
} else {
    create another file containg the alternate class definition
    include that other file
}

Как сказал @Gordon в комментарии, возможность сделать вещи немного проще - использовать Zend_CodeGenerator, чтобы помочь с этой задачей генерации кода.


Как уже отмечалось, пользователи вряд ли будут иметь доступ на запись в каталог library, но ничто не мешает вам создавать эти файлы в другом каталоге " cache " - в конце концов, вероятно, ваше приложение имеет доступ на запись хотя бы к одному каталогу:

  • Для кеша ^^
  • Или, по крайней мере, для бревен


Решением было бы использовать eval:

  • построить строку, содержащую определение класса
  • eval использовать

Но я бы не стал этого делать, по крайней мере, по двум причинам:

  • Отладка, вероятно, будет сложнее - даже для почти пустого файла / строки
  • Использование файла означает, что существует возможность кэширования кода операции (APC или аналогичные инструменты)
  • И, в-третьих, подумав об этом: наличие файла означает, что ваша IDE может его проанализировать - может помочь с завершением кода, подсказкой типа, ...


Увидев ваше обновление, я попробовал условное объявление:

if (false) {
    class A {
        public $a = 10;
    }
} else {
    class A {
        public $a = 20;
    }
}

$a = new A();
var_dump($a);

Меняя условие с ложного на истинное и наоборот, я получаю два альтернативных вывода:

object(A)[1]
  public 'a' => int 20

object(A)[1]
  public 'a' => int 10

Так что ... похоже, работает!
(Я удивлен, я думал, что это возможно только для функций!)

Но, тем не менее, мне не очень нравится эта идея ... Не уверен, как она себя ведет в IDE - и мне нравится иметь один класс на файл ...
(Да, личное мнение)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...