Я собираюсь дать вам весьма необычное обсуждение контроля ошибок.
Много лет назад я встроил в язык очень хороший обработчик ошибок, и хотя некоторые названия изменились, принципы обработки ошибок остались прежними. У меня была специально созданная многозадачная ОС, и я должен был иметь возможность восстанавливать данные после ошибок на всех уровнях без утечек памяти, роста стека или сбоев. Далее следует мое понимание того, как должны работать ошибки и исключения и чем они отличаются. Я просто скажу, что не понимаю, как работает функция try catch, поэтому в некоторой степени предполагаю.
Первое, что происходит под прикрытием обработки ошибок, - это переход из одного состояния программы в другое. Как это сделать? Я к этому вернусь.
Исторически ошибки старше и проще, а исключения новее, немного сложнее и эффективнее. Ошибки работают нормально до тех пор, пока вам не придется их всплескивать, что равносильно передаче сложной проблемы вашему руководителю.
Ошибки могут быть числами, например номерами ошибок, а иногда и одной или несколькими связанными строками. Например, если возникает ошибка чтения файла, вы можете сообщить, что это такое, и, возможно, корректно завершиться ошибкой. (Эй, это шаг вперед от того, чтобы просто рушиться, как в старые времена.)
Об исключениях нечасто говорят, что исключения - это объекты, расположенные в специальном стеке исключений. Это как стек возврата для потока программы, но он содержит состояние возврата только для попыток и уловов ошибок. (Раньше я называл их ePush и ePop, а? Abort - это условный бросок, при котором ePop восстанавливается до этого уровня, а Abort - это полный кубик или выход.)
Внизу стека находится информация об исходном вызывающем объекте, объекте, который знает о состоянии, когда была запущена внешняя попытка, а это часто бывает при запуске вашей программы. На вершине этого или следующего слоя в стеке, где up являются дочерними элементами, а down являются родителями, является объектом исключения следующего внутреннего блока try / catch.
Если вы помещаете попытку внутри попытки, вы кладете внутреннюю попытку поверх внешней. Когда во внутренней попытке возникает ошибка, и либо внутренний catch не может ее обработать, либо ошибка передается внешней попытке, тогда управление передается внешнему блоку catch (объекту), чтобы узнать, может ли он обработать ошибку, т.е. ваш руководитель.
Итак, что на самом деле делает этот стек ошибок, так это возможность отмечать и восстанавливать поток программы и состояние системы, другими словами, он позволяет программе не разрушать стек возврата и не портить вещи для других (данных), когда что-то идет не так. Таким образом, он также сохраняет состояние любых других ресурсов, таких как пулы распределения памяти, и может очистить их, когда будет выполнен перехват. В общем, это может быть очень сложной задачей, и поэтому обработка исключений часто выполняется медленно. В общем, в эти блоки исключений нужно включить довольно много состояний.
Таким образом, блок try / catch устанавливает состояние, к которому можно вернуться, если все остальное испортилось. Это как родитель. Когда наша жизнь портится, мы можем снова упасть на колени к родителям, и они все исправят.
Надеюсь, я тебя не разочаровал.
Errors are generally unrecoverable
<- на самом деле это не совсем так.E_ERROR
иE_PARSE
являются двумя наиболее распространенными неисправимые ошибки (есть несколько других) , но подавляющее большинство ошибок , которые вы увидите в разработчика извлекаемые (E_NOTICE
, иE_WARNING
др). К сожалению, обработка ошибок PHP представляет собой полный беспорядок - все виды вещей вызывают ошибки без необходимости (например, подавляющее большинство функций файловой системы). В общем случае исключения - это «способ ООП», но, к сожалению, некоторые из собственных API ООП PHP используют ошибки вместо исключений :-(