Сайт упал из-за ECHO
Привет, уважаемые читатели!
В данной статье я хотел описать решение проблемы с которой я столкнулся, на решение проблемы у меня ушло три часа, вот я не хочу, чтобы мои читатели не тратили так много времени.
Также данная статься предназначена для людей которые имеют представление об ООП, приведениях типов, в общем, с углубленным знанием PHP.
Итак. Я работаю с ZendFramework. В одном из проектов который я создаю было задача построения не простой формы, следовательно вывести во вьюхе:
<?php echo $this->form;?>
я не смог из-за сложной верстки (декорировать на зенде — дольше, чем на голом ХТМЛе создать), я просто разобрал созданную в контроллере форму по элементам:
$itemsList = $this->form->getElements ();
в таком виде я получил массив всех элементов, ключами массива служили название полей в форме, а значение — объект данного поля (валидаторы, декораторы и тд).
При построении кнопок в данной форме я воспользовался конструкцией тернарного оператора:
<?php echo isset($itemsList["submit"]) ? $itemsList["submit"] : ''?> <?php echo isset($itemsList["reset"]) ? $itemsList["reset"] : ''?>
В форме при разных условиях часть кнопок отсутствовала, поэтому юзал условия.
При такой конструкции сайт ВАЛИТСЯ!!! Никаких сообщений нет, трейса нет, в логе-апача ничего нет — полный ГОЛЯК! Нашел я эту проблему методом «научного тыка».
Ну как ни у кого нет мысли почему эти строки валили сайт, еще скажу, если выводить какую-то одну из строк — все ОК?!
В общем дело в том, что именно оператор ECHO виновен, он не смог преобразовать объект в строку и выдать её, при этом никакого предупреждения не выдав!!!!!!!!
Если переписать эти строки вот так:
<?php print isset($itemsList["submit"]) ? $itemsList["submit"] : ''?> <?php print isset($itemsList["reset"]) ? $itemsList["reset"] : ''?>
, т.е. заменить echo на print все нормально срабатывало.
Как бы я не крутил конструкция с эхо, скобочки разные, короткое сокращение эхо, и тд ничего не происходило. Помогло только явное приведение к строке с помощью конструкции (string), или конкатенация с пустой строкой, или приведение к типу с помощью ООП метода __toString();
<?php echo isset($itemsList["submit"]) ? (string)$itemsList["submit"] : ''?> <?php echo isset($itemsList["reset"]) ? (string)$itemsList["reset"] : ''?>
<?php echo isset($itemsList["submit"]) ? $itemsList["submit"].' ' : ''?> <?php echo isset($itemsList["reset"]) ? $itemsList["reset"].' ' : ''?>
<?php echo isset($itemsList["submit"]) ? $itemsList["submit"]->__toString() : ''?> <?php echo isset($itemsList["reset"]) ? $itemsList["reset"]->__toString() : ''?>
Но самое, что для меня не понятное, почему если, я расписал условие в полном объеме:
if(isset($itemsList["submit"])) { echo $itemsList ["submit"]; } if(isset($itemsList["reset"])) { echo $itemsList ["reset"]; }
все выполняется, заметьте, преобразованием типа я не занимался!!!
Вот часть кодов, может кто хочет протестировать:
Класс формы
public function __construct($options = null) { ..... $this->_options = $options; ..... } public function init() { ..... $this->addElement( 'submit', 'submit', array( 'label' => 'submit', 'class' => 'but', 'decorators' => array('ViewHelper'), 'title'=>'submit' ) ); $this->addElement( 'submit', 'reset', array( 'label'=>'reset', 'class' => 'but', 'decorators' => array('ViewHelper'), 'title'=>'reset' ) ); ..... } protected $_options = array();
Контроллер
$form = new Module_Forms_MyForm(array('some options')); ..... $this->view->form = $form;
Вьюха
$itemsList = $this->form->getElements (); <form ....> ..... <?php echo isset($itemsList["submit"]) ? $itemsList["submit"] : ''?> <?php echo isset($itemsList["reset"]) ? $itemsList["reset"] : ''?> ..... </form>
Плиз, оставь свои мнения, почему в тернарном операторе эхо не сработало, а в общем условии — все ок!! Очень интересно знать, отвечу на любые вопросы.
UPD: Забыл сказать, все это без каких либо изменений работет по виндой, но подлинухом не работает!
Статья просмотренна 73476 раз, зашло посетителей 18521