Комментарии

Исключения и блоки try/catch
( 0 Голосов )

В версии 5 языка РНР введено понятие обработки исключений, а также внедрены средства их генерирования и перехвата в блоках try/catch. Аналогичные понятия и средства имеются в Java и других языках ООП. Основной принцип обработки исключений заключается в следующем: если в программе выполняется какая-нибудь рискованная операция, которая не может быть полностью проконтролирована в рамках данной программы, то необходимо организовать проверку ошибок. И блок try/catch позволяет сделать это просто и удобно.

С этой целью рискованный код, способный генерировать исключения, помещается в блок try. При обнаружении условия, приводящего к ошибке, выполняется команда, генерирующая новое исключение. В итоге создается объект исключения, а управление ходом выполнения программы передается коду из блока catch. Исходя из типа исключения в этом блоке могут быть выполнены все необходимые действия. Это может быть простой возврат логического значения false или обработка исключения в зависимости от его характера.

Исключения можно генерировать в теле методов и без блоков try/catch. Но тогда метод должен вызываться из блока try, чтобы в блоке catch было перехвачено исключение, которое может быть сгенерировано в этом методе. Об этом должно быть непременно указано в блоке документации на методы, генерирующие исключения, чтобы программирующие знали, как пользоваться такими методами в блоках try.

Подобного рода обработка исключений отсутствовала до появления версии Joomla 1.6, для нормального функционирования которой требуется версия 5.2 или более поздняя версия языка РНР. Но по мере написания кода для Joomla и обновления старых классов такая обработка исключений будет все чаще появляться в кодовой базе Joomla.

А теперь вернемся к методу loadForm () из предыдущего кодового блока. После установки в переменной $form объекта типа JForm проверяется, загружаются ли данные в форму. В качестве третьего аргумента в сигнатуре метода loadForm () указывается ассоциативный массив $options. В данном примере требуется предварительно загрузить данные, предназначенные для формы, для чего в ассоциативный массив вводится элемент loaddata с логическим значением true.

При соблюдении условия загрузки данных вызывается метод loadFormData (), получающий любые загруженные ранее данные, но, как правило, они отсутствуют. Если элемент редактируется в первый раз или только создается, то вызывается метод $this->getltem(), в котором создается объект типа JObject с полями для формы. И если элемент уже существует, то для него получаются данные, тогда как для нового элемента получаются значения, исходные по умолчанию. А если таковые не указаны в полях, то получаются пустые значения.

Когда же используются данные из текущего сеанса работы? Допустим, пользователь заполнил форму с целью ввести новый элемент, но некоторые данные в этой форме оказались недостоверными, например, пропущено заглавие или продублировано поле псевдонима. В этом случае операция сохранения не завершится успешно, а следовательно, данные не сохранятся в базе данных. И тогда пользователю предстоит неприятная процедура повторного ввода данных во всех полях формы, чтобы исправить единственную допущенную им ошибку. Во избежание подобной ситуации введенные данные сохраняются в текущем сеансе работы пользователя. И только после успешного их сохранения в базе данных они удаляются из данного сеанса работы. Таким образом, данные получаются из базы данных с помощью метода get Item () или же из текущего сеанса работы с помощью метода getUserState ().

И последней операцией в методе loadFormData () является проверка наличия категории в запросе или сеансе работы. Если категория имеется, она устанавливается для данных как исходная по умолчанию. И наконец, из данного метода возвращается объект типа JObject, сохраняемый в переменной $data из вызывающего метода loadFormData (). Если же загружать данные в форму не требуется, в переменной $data устанавливается пустой массив.

Следующая строка кода из метода loadFormData () имеет большое значение:

$this->preprocessForm($form, $data);

В этой строке кода вызывается метод из класса JModelForm, поскольку он не переопределяется в подклассах, производных от класса JModelAdmin или WeblinksModelWebl ink. Ниже приведен исходный код данного метода.

protected function preprocessForm(JForm  $form, $data, $group = 'content') {
// импортировать  подходящую группу подключаемых модулей
JPluginHelper::importPlugin($group);
// получить диспетчер
$dispatcher = JDispatcher::getlnstance();
// инициировать событие, связанное  с подготовкой формы $results = $dispatcher->trigger('onContentPrepareForm', array($form, *S>$data) ) ;
// проверить ошибки, возникающие  при подготовке  формы
(count($results) && in_array(false, $results, true)) {
// получить  последнюю ошибку
$error =  $dispatcher->getError ();
// преобразовать ошибку, если требуется, в исключение if (!JError::isError($error)) { throw new Exception($error);

В данном методе инициируется событие onContentPrepareForm. Это событие было внедрено в версии Joomla 1.6 специально для объектов типа JForm. Оно позволяет разрабатывать подключаемые модули для видоизменения объектов типа JForm, прежде чем они будут воспроизведены в окне браузера. Такие подключаемые модули делают доступным объект типа JForm (в переменной $form) и массив данных (в переменной $data). Пример применения события onContentPrepareForm был приведен в главе 5 при создании подключаемого модуля из файла myregistration2 .php. В том примере подключаемый модуль использовался для ввода в форму ряда новых полей. Но с тем же успехом подключаемые модули можно использовать и для удаления, проверки достоверности или редактирования объектов типа JForm.

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

А после возврата обратно в метод loadForm () вызывается метод bind () из родительского класса JForm, расположенного вверх по иерархии, поскольку этот метод не переопределяется ни в одном из его подклассов. В данном методе проверяется наличие в объекте типа JForm достоверного объекта типа JXMLElement, определенного в поле, размеченном в коде XML, а также наличие объекта или массива в переменной $data. После этого поля формы сопоставляются с элементами данных и в каждом из них устанавливается соответствующее значение.

И снова происходит возврат в метод loadForm () ближе к концу блока try. Если при выполнении кода в любом из методов было сгенерировано исключение, его необходимо обработать. С этой целью выполняется приведенный ниже блок catch.

} catch (Exception  $е) {
$this->setError($e->getMessage()); return false; }

В этом кодовом блоке характер ошибки устанавливается для данной модели, исходя из сообщения, получаемого от объекта исключения, а затем возвращается логическое значение false вызывающему методу loadForm (). Если же во время выполнения блока try исключения не сгенерированы, блок catch пропускается.


Понравился материал? Пригодилась информация? Плюсани в социалки!


Теги:
 
Похожие новости