Задать вопрос

В 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}
}
  • Вопрос задан
  • 1234 просмотра
Подписаться 7 Простой 2 комментария
Решения вопроса 3
FanatPHP
@FanatPHP
Чебуратор тега РНР
Очень хороший вопрос и тема, в которой самое чудовищное количество самых дремучих северий на единицу кода.

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

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

Пример: В обоих приведенных выше случаях мы имеем масло масляное: попытка подменить пхп в выборосе ошибки. Вопрос - зачем? Если файл не найден, то РНР сам прекрасно сообщит нам об ошибке, причем в подробностях, и скажет в чем конкретно заключается проблема. А по строчке "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 Куратор тега PHP
Вариант 1 - ненужный, так как Вариант 2 обработает все. Более того, Вариант 1 гарантирует лишь то, что код условия не выполнится только тогда, когда файла, на момент проверки, нет и не было. Но может случиться так, что в период между проверкой и чтением файла, файл будет удален, или кеш не обновился, и тогда ты обломаешься со своей проверкой.
Ответ написан
Комментировать
solotony
@solotony
покоряю пик Балмера
первый случай это не обработка ошибки, а обработка ситуации "отсутствия файла" - например предлагается создать новый, спросить имя, выбрать путь и т.д.

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

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

---

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

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

Похожие вопросы