В PHP канонично сначала проверить, потом сделать или попробовать и обработать ошибку?

Собственно, сабж. Try - Catch или все необходимые проверки перед выполнением кода?
UPD: пример. Что по идеологии подходит к PHP? (примеры на псевдокоде)
# Вариант 1:
f getFileContent(filename){
if (!file_exists(filename)) {error: file not found}
return file_content(filename)
}

# Вариант 2:
f getFileContent(filename){
try return file_content(filename)
catch FileNotFoundException {error: file not found}
}
  • Вопрос задан
  • 1206 просмотров
Решения вопроса 3
FanatPHP
@FanatPHP
Чебуратор тега PHP
Очень хороший вопрос и тема, в которой самое чудовищное количество самых дремучих северий на единицу кода.

В общем случае, по умолчанию, никаких проверок и траев с кетчами быть не должно.

Я понимаю, что это звучит богохульством для среднего пользователя похапе, но в реальности программы пишутся совсем по-другому.

Пример: В обоих приведенных выше случаях мы имеем масло масляное: попытка подменить пхп в выборосе ошибки. Вопрос - зачем? Если файл не найден, то РНР сам прекрасно сообщит нам об ошибке, причем в подробностях, и скажет в чем конкретно заключается проблема. А по строчке "file not found" иди гадай - путь ли кривой или в имени файла опечатка, или вообще пустоту передали.

Любые проверки надо делать только тогда, когда есть осмысленный сценарий их обработки.

И обсуждать выше приведенные примеры имеет смысл только если автор вопроса предоставит такой сценарий. тупое error: file not found таким сценарием не является. Так что в общем случае оставляем код в покое и не устраиваем никакого карго культа из перехвата ошибок.

Если чисто выбирать между двумя действиями (проверка и чтение) и одним (сразу читаем, потом ловим исключение),

то последнее предпочтительнее, поскльку это атомарная операция, в то время как между проверкой и чтением состояние системы сожет измениться (файл может быть удален).

Но повторюсь, если нет никакого осмысленного сценария обработки ошибки, то ловить её не надо.
Ответ написан
sergiks
@sergiks Куратор тега PHP
♬♬
В таком примере, как вы привели, if() проверяет только условие существования файла или директории. А try-catch обработает бОльшее число ситуаций: если это не файл, а директория, если права не позволяют читать, если устройство гакнулось и не прочиталось.
пример автора вопроса
# Вариант 1:
f getFileContent(filename){
  if (!file_exists(filename)) {error: file not found}
  return file_content(filename)
}

# Вариант 2:
f getFileContent(filename){
  try return file_content(filename)
  catch FileNotFoundException {error: file not found}
}


По замыслу if отличается тем, что проверяет предусмотренные варианты, а исключения кидаются в непредусмотренных. Все бросаемые исключения надо документировать, чтобы их кто-то где-то, в итоге, поймал.

Условные операторы только для локальной логики внутри функции. Отлов исключений может иметь многоуровневую иерархию вне функции, класса. Например, случай не файла-а-папки отловится в одном, а случай нечитаемого сломанного устройства – на самом верхнем уровне всего приложения. И по-разному будут обработаны.

Внешние материалы по теме:
  1. Пост по теме (на англ.)
  2. скорость выполнения с исключениями и без (без быстрее)
  3. Exception patterns, в частности:


Ответ написан
glaphire
@glaphire Куратор тега PHP
PHP developer
Try-catch отловит ошибку внутренней логики вызванного кода, а проверки передаваемых данных должны гарантировать, что с Вашей стороны все сделано правильно, т.е. ответ в том, что эти подходы не взаимозаменяемы
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
Minifets
@Minifets
Hello world!!!
Очень хорошие рассуждения, только вот они не учли один факт. Функции в php, которые работают с файлами не бросают Exception, а только Warning (да-да, при небольших модификациях можно из Warning сделать Exception).

Поэтому в php канонично, если в функции/методе есть throw - ее нужно обернуть в try - catch, а если функция позвращает true/false, то использовать if.

Ну и дополню, есть в функции есть throw, то проверки if, которые обходят этот throw, по своей сути - дублирование кода.
Ответ написан
profesor08
@profesor08
Вариант 1 - ненужный, так как Вариант 2 обработает все. Более того, Вариант 1 гарантирует лишь то, что код условия не выполнится только тогда, когда файла, на момент проверки, нет и не было. Но может случиться так, что в период между проверкой и чтением файла, файл будет удален, или кеш не обновился, и тогда ты обломаешься со своей проверкой.
Ответ написан
solotony
@solotony
ушел пить чай %)
первый случай это не обработка ошибки, а обработка ситуации "отсутствия файла" - например предлагается создать новый, спросить имя, выбрать путь и т.д.

стоит иметь ввиду что между проверкой существования файла и попыткой его открытия есть временной лаг, и за время между проверкой и открытием может много чего случиться.

второй случай - это именно обработка ОШИБКИ.

---

резюме: если цель открыть заведомо существующий файл, то 2-й способ "каноничнее".
Ответ написан
@Nujabes37
:DEATH
Не совсем понятен вопрос, но. Try catch, нужен для обработки исключений. Проверки (если вы про конструкцию if (..)) нужны для булевых операций, все.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы