Несмотря на то, что есть некоторые дискуссии по этой проблеме, я хотел бы проверить на определенном примере, какой будет лучший подход.
Вместо того, чтобы использовать существующие решения, я создал свой собственный уровень персистентности (как и многие другие). Итак, мой подход также под вопросом.Php (eval vs call_user_func vs variable functions ...)
Для каждой таблицы в db у меня есть класс модели, который имеет соответствующие геттеры и сеттеры и некоторые обязательные методы. Я также создал только один общий класс DAO, который обрабатывает все типы объектов модели.
Так, например, чтобы сохранить любой объект модели, я создаю экземпляр класса genericDAO и метод сохранения вызова, который передаю объект модели как атрибут. Проблема заключается в том, что в среде выполнения genericDAO класс не знает объект модели whitch, который он получает, и какие методы (геттеры и сеттеры) существуют в нем, поэтому мне нужно вызвать метод обязательной модели модели, который извлекает список атрибутов в виде нескольких строковых массивов.
Например, для каждого атрибута есть массив (table_column_name, attribute_name, is_string).
Когда я вызываю функцию сохранения она выглядит следующим образом:
public function save(&$VO) {
$paramArray = $VO->getParamArray();//get array of attributes
$paramIdArray = $paramArray[0]; //first attribute is always id
/*create and execute getId() and store value into $void to check if it's save or update*/
eval('$voId = $VO->get'.ucfirst($paramIdArray[1]).'();');
...
В настоящее время я использую Eval для выполнения этих методов, но, как это хорошо известно Eval очень медленно.
Я имею в виду изменения, что в методе call_user_func
что-то вроде:
$voId = call_user_func(array($VO, 'get'.ucfirst($paramIdArray[1])));
Но также есть и другие решения. Я, возможно, использовать что-то вроде этого
$method = 'get'.ucfirst($paramIdArray[1]));
$voId = $VO->$method();
или еще
$method = 'get'.ucfirst($paramIdArray[1]));
$voId = $VO->{$method}();
Что бы быть лучшим способом?
Я думаю, что 'call_user_func()' все еще единственный способ вызвать анонимную функцию, хранящуюся в переменной объекта: '$ o- > f = function() {}; 'попытка сделать' $ o-> f() 'приведет к тому, что' $ o не имеет метода с именем 'f'' warning. – Mchl
@Mchl: '$ c = $ o-> f; $ c(); 'будет работать. Или вы можете реализовать магический метод '__call', чтобы сделать это за вас. Но вы не имеете * использовать 'call_user_func'. И в этом смысл того, что я пытался сказать. Это не делает ничего, что вы не можете сделать на родном языке ... Это может быть проще сделать и прочитать, но это не делает ничего особенного ... – ircmaxell
Ах да. Забыл о '$ c = $ o-> f; $ c(); ', вы правы в этом. – Mchl