РНР 5 в подлинникеСтраница 339 из 554 |
||
|
Гпава 34. Обработка ошибок и исключения 685 рования диагностического сообщения (его можно потом перехватить при помощи функции-обработчика). Например, функция fopeno при невозможности открытия файла возвращает false; и мы в дальнейшем должны проверить результат на "истинность", как уже неоднократно делали это раньше. Данный метод имеет три недостатка. □ Главный недостаток — программист может просто забыть (или полениться — это одно и то же) проверить возвращенное функцией значение, и продолжить выполнение программы так, будто бы ничего не произошло. В большинстве случаев это породит лавинообразное нарастание количества диагностических сообщений, не имеющих никакого отношения к сути проблемы. □ Любое значение, возвращаемое функцией, может быть по смыслу допустимым. Например, стандартная функция unserialize О распаковывает некоторую переменную из ее строкового представления (сгенерированного вызовом serialize!)) и возвращает ее исходное значение. Что должна вернуть функция в случае ошибки? Если, например, null, то где гарантия, что действительно произошла ошибка, а исходная переменная не содержала просто значение null до упаковки? □ Код восстановления приходится постоянно дублировать. Например, если нам в программе нужно открыть 10 разных файлов, мы будем вынуждены 10 раз проверить возвращаемое функцией fopeno значение/Легко представить, как сильно это "раздует" программу. Еще хуже вы себя почувствуете, если вспомните, что в будущем может понадобиться модифицировать код восстановления: придется делать это в 10 местах. Ненормальное состояние программы Часто одного лишь недопустимого возвращаемого значения оказывается недостаточно для хранения всей информации. Поэтому в дополнение к предыдущему способу в РНР иногда применяется запись информации об ошибке в некоторую внутреннюю переменную, которую можно будет в дальнейшем считать и проанализировать другими функциями. Так работают, например, инструменты для доступа к MySQL в РНР: mysqi_connect {), mysqi_query {) и т. д. Вы можете проверить, не вернули ЛИ фуНКЦИИ "ЛОЖНОе" Значение, а потом ИСПОЛЬЗОВаТЬ mysql_error () или mysqi_errno {) для получения дополнительной информации. Состояние программы, в котором когда-то ранее произошла ошибка, требующая дополнительного анализа, называют ненормальным. Главный недостаток ненормального состояния в том, что если вдруг произойдет еще одна ошибка, то информация о ней "затрет" предыдущую. Таким образом, мы вынуждены периодически проверять, не находится ли программа в ненормальном состоянии, и предпринимать дополнительные действия. Это сильно увеличивает код; кроме того, программист может как-нибудь просто забыть вставить в программу требуемые проверки. Вызов функции-обработчика Этот способ мы рассматривали применительно к обработке несерьезных ошибок. Там же мы говорили, что для перехвата серьезных ошибочных ситуаций он применим мало. Действительно, функция-обработчик имеет в своем распоряжении те же 686 Часть V. Объектно-ориентированное программирование на РНР самые три альтернативы, которые мы рассматривали выше. Она не получает в свое распоряжение ни текущие локальные переменные программы, ни информацию о том, что следует делать в каждом персональном случае. Механизм обработки исключений или, как чаще всего говорят в мире ООП, просто "исключения" (exceptions) — это технология, позволяющая писать код восстановления после серьезной ошибки в удобном для программиста виде. С применением исключений перехват и обработка ошибок, наиболее слабая часть в большинстве программных систем, значительно упрощается. Концепция исключений базируется на общей (и достаточно естественной) идее объектно-ориентированного программирования: данные должны обрабатываться в том участке программы, который имеет максимум сведений, как это делать. Если в некотором месте еще не до конца известно, какое именно преобразование должно быть выполнено, лучше отложить работу "на потом". С использованием исключений код обработки ошибки явно отделяется от кода, в котором ошибка может возникнуть. Исключения также позволяют удобно передавать информацию о возникшей ошибке вниз по дереву (стеку) вызовов функций. Таким образом, код восстановления может находиться даже не в текущей процедуре, а в той, что ее вызывает. Мы поговорим об этой важной особенности в разд. "Раскрутка стека" далее в этой главе. Базовый синтаксис Итак, исключение — это некоторое сообщение об ошибке вида "серьезная". При своей генерации оно автоматически передается в участок программы, который лучше всего "осведомлен", что же следует предпринять в данной конкретной ситуации. Этот участок называется обработчиком исключения. Любое исключение в программе представляет собой объект некоторого класса, создаваемый, как обычно, оператором new. Этот объект может содержать различную информацию, например, текст диагностического сообщения, а также номер строки и имя файла, в которых произошла генерация исключения. Допустимо добавлять и любые другие параметры. Прежде чем идти дальше, давайте рассмотрим простейший пример вызова обработчика (листинг 34.2). Заодно получим представление о синтаксисе исключений. [Листинг 34.2. Файл simple.php <?php ## Простой пример использования исключений, echo "Начало программы.<Ьг>"; try { // Код, в котором перехватываются исключения, echo "Все, что имеет начало...<Ьг>"; Исключения
|
| |
|
В начало ←предыдущая следующая→ ... 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 ... | ||