Дополнительный параметры при создании экземпляра класса без перегрузки конструктора.
Ожидает приглашения
Недавно столкнулся со следующей проблемой: надо было в symfony создать класс формы, в которой заранее неизвестен набор полей. Т.е. класс должен был конфигурироваться динамически в зависимости от того, какие поля туда передаются. Ну а проблема заключалась как раз в том, как именно передавать туда эти поля.
По собственной неопытности, я переопределил конструктор класса sfForm.
В чем тут ошибка? А в том, что если в новой версии symfony изменятся параметры этого класса, то и в классе моей формы придется их изменить. Ну и как вы думаете, вспомнил бы я об этом? Ох, врядли.
Да и вообще, чем меньше приложение зависит от версий инструментов, которыми оно разрабатывается, тем лучше, верно ведь?
На ошибку мне указал старший товарищ, мой начальник. Он же и научил, как делать иначе.
Итак, есть два способа. Один способ – это, если все-таки очень хочется использовать перегрузку конструктора, а другой – позволяет избежать подобного действа, благодаря статическим переменным.
Способ первый.
Переопределяем конструктор так:
Такая реализация позволяет избежать всяких волнений, связанных с изменениями в новых версиях фреймворка. Но это, все же, как-то смахивает на некий хак. Да и вообще, я подозреваю, что call_user_func – это специальная функция для костылей и хаков.
Способ второй.
Определяем в классе формы статическую переменную:
А потом экземпляры формы создаем так:
По собственной неопытности, я переопределил конструктор класса sfForm.
class MyForm extends sfForm
{
public function __construct(array $fields, $defaults = array(), $options = array(), $CSRFSecret = null)
{
$this->fields = $fields;
parent::__construct($defaults, $options, $CSRFSecret);
}
…
В чем тут ошибка? А в том, что если в новой версии symfony изменятся параметры этого класса, то и в классе моей формы придется их изменить. Ну и как вы думаете, вспомнил бы я об этом? Ох, врядли.
Да и вообще, чем меньше приложение зависит от версий инструментов, которыми оно разрабатывается, тем лучше, верно ведь?
На ошибку мне указал старший товарищ, мой начальник. Он же и научил, как делать иначе.
Итак, есть два способа. Один способ – это, если все-таки очень хочется использовать перегрузку конструктора, а другой – позволяет избежать подобного действа, благодаря статическим переменным.
Способ первый.
Переопределяем конструктор так:
public function __construct()
{
$args = func_get_args();
<вырезать из $args свой параметр>;
call_user_func(array('parent', '__construct'), $args); // тут $args уже без левого параметра.
}
Такая реализация позволяет избежать всяких волнений, связанных с изменениями в новых версиях фреймворка. Но это, все же, как-то смахивает на некий хак. Да и вообще, я подозреваю, что call_user_func – это специальная функция для костылей и хаков.
Способ второй.
Определяем в классе формы статическую переменную:
static $fields;
А потом экземпляры формы создаем так:
MyForm::$fields = my_fields;
$this->form = new MyForm();
Пожалуй, статическую переменную в форме следует пометить комментарием, где и как ей присваивается значение, и зачем это вообще делается.
Чем хорош этот способ? Тем, что мы остаемся исключительно в рамках нашего кода и не лезем в код symfony. Ну и поизящнее выглядит, не находите?