Все работает как положено. Столкновение имен отсутствует, поскольку при использовании $ this-> createElement () созданный вами элемент фактически нигде не сохраняется. При таком подходе вы должны явно сохранить элемент в некоторой переменной (например, переменной-члене), а затем добавить его в набор элементов формы, используя $ this-> addElement ().
Если вы посмотрите на исходный код Zend_Form, вы заметите, что:
1- При вызове createElement () элемент создается и сразу возвращается; другими словами, элемент нигде не хранится внутри, поэтому вы должны сохранить его самостоятельно и добавить в форму:
public function createElement($type, $name, $options = null)
{
...
$element = new $class($name, $options);
return $element;
}
2- Когда вы вызываете addElement (), элемент затем добавляется в форму и внутренне сохраняется в массиве защищенных элементов, называемом _elements. Это то же самое, что и делать:
$this->id = $this->createElement('text', 'id', array(...));
, который волшебным образом вызывает addElement () (как указано пользователем user594791 в его комментарии). Вы также можете напрямую поместить элемент в массив _elements, но я советую против этого, потому что addElement () выполняет некоторую дальнейшую обработку. Конфликты имен отсутствуют, потому что вы выполняете одно и то же действие дважды (как указано Марчином в другом ответе), а во второй раз вы перезаписываете элемент самим собой.
Наконец, я также советую не создавать элементы, которые вы не будете использовать (пустая трата ресурсов и не очень хорошая практика программирования). Желательно сохранить ассоциативный массив конфигураций для возможно необходимых элементов в вашем родительском классе; затем в ваших подклассах вы создаете только те элементы, которые вам действительно нужны, используя соответствующие массивы конфигурации, которые были предварительно сохранены в родительском классе. Пример:
class ParentForm extends Zend_Form {
...
protected $_elementConfig;
...
public function init() {
...
// Add element configuration, but don't instantiate element right now
$this->_elementConfig = array();
// Element 1, a text input
$this->elementConfig['myTextInput'] = array(
'Text',
array(
'label' => 'Theme',
'description' => 'Main application theme',
'maxLength' => 128,
'validators' => array(
array('StringLength', false, array('max' => 128))
),
'filters' => array(
array('HtmlEntities')
)
)
);
// Element 2, a submit button
$this->elementConfig['mySubmitButton'] = array(
'Submit',
array(
'label' => 'Save'
)
);
// Element 3, something else
...
}
...
}
class ChildForm extends ParentForm {
public function init() {
parent::__construct(); // Parent init() is called by the parent constructor
...
// Will use the submit button
$this->addElement(
$this->_elementConfig['mySubmitButton'][0], // Type of element
'mySubmitButton', // Name of element
$this->_elementConfig['mySubmitButton'][1] // Config of element
);
}
}
Если у вас много элементов и вы не хотите сильно загрязнять родительский метод init (), я предлагаю вам поместить полные определения элементов во внешний файл, который может быть либо файлом PHP, который возвращает массив PHP с полная конфигурация, XML-файл, INI-файл или любой другой формат, поддерживаемый Zend_Config (вы можете определить элементы без фрагмента реального кода PHP - здесь - внизу страницы - пример определения элемента с файлом INI).