OutOfRangeException и OutOfBoundsException
PHP определяет два SPL исключения для поврежденных ключей:
OutOfRangeException
: исключение, возникающее при запросе незаконного индекса. Это ошибки, которые должны быть обнаружены во время компиляции.
OutOfBoundsException
: исключение, если значение не является допустимым ключом. Это ошибки, которые не могут быть обнаружены во время компиляции.
как PHP не компилируемый язык различие между время компиляции и время выполнения кажется странным, и поэтому мне трудно понять, какое исключение использовать, когда.
в настоящее время я понимаю, что надо бросать...
... OutOfRangeException
Если ключ фундаментально и по своей сути искажен, например, если массив передается как ключ.
... OutOfBoundsException
если ключ в целом в порядке, но не находится в некоторых границах, например, если 100
передается, но 50
максимальная ключ.
правильно ли это понимание?
6 ответов
хотя PHP не имеет классического " времени компиляции "(или компилятора, который делает много статических проверок), я бы рассматривал" время компиляции "как" скорее статический материал, который я сделал неправильно при написании кода "и" время выполнения "как"моя логика, ввод или проверка были отключены в какой-то момент".
поэтому мое предложение было бы так:
"Compile Time" / "OutOfRangeException"
: ошибка всегда может быть исправлена в исходном коде без или с очень маленькой логикой.
I всегда беру цифры от 1-10 и 11
"Run Time" / "OutOfBoundsException"
: ошибка связана с неправильным использованием во время выполнения.
вы создали меня и сказали мне взять значения от 1 до 5, затем вы положили 7. Не вычисляет
или
вы запрашиваете индекс, которого нет, потому что вы не положили его туда, как вы должны
пример:
я ожидал бы SplFixedArray бросить OutOfBoundsException
потому что это размер динамический и может шанс во время выполнения, в то время как я ожидал бы что-то вроде Calender::getMonthName
бросить и OutOfRangeException
потому что количество месяцев определенно фиксируется во время" компиляции/записи".
массив объектов пример:
Say $array-это объект, который реализует ArrayAccess, который вы можете бросить OutOfBoundsException
при следующих обстоятельствах:
$array['bar'];
$array[7];
поскольку значения-это то, что вы могли ожидать для ArrayAccess, но это не делает смысл в случае SplFixedArray(5). Альтернативы были бы DomainException
или, может быть,RangeException
An OutOfRangeException
в таких случаях:
$calendar->getMonth(15);
как положить массив или новый класс, безусловно, есть какой-то больший логический недостаток в коде, который обычно является результатом простой ошибки "О, я положил неправильную переменную" программистом. Альтернативой (возможно, предпочтительной) будет UnexpectedValueException
и InvalidArgumentException
.
для таких случаев, как:
$array[array()];
$array[new StdClass];
некоторые из альтернативные исключения кажутся более подходящими.
сравнения с миром Java, в котором исключение для использования, когда не всегда применимо, поскольку разработчики Java имеют проблему дополнений.
проверенные / непроверенные исключения. Со многими людьми, утверждающими, что все, что не является исключением времени выполнения, имеет очень ограниченное использование в Java / не должно использоваться много внутри), эти имена потеряли часть своего первоначального значения и намерения.
мой собственный взгляд на это:
LogicException
используйте для любых ошибок разработчик сделал, например, ошибки при программировании/сборка приложения. Надеюсь, они будут пойманы, когда разработчик запускает свои UnitTests (что будет эквивалентно времени компиляции). Эти исключения никогда не должны возникать на производственном сайте, поскольку они являются ошибками в программном обеспечении как таковом.
RuntimeException
:
использовать для любого ошибки пользователей сделал или что результат от недопустимых данных, помещенных в приложение во время выполнения. Это ошибки, которые можно предвидеть, но не полностью предотвратить с помощью UnitTests, например, те, которые могут произойти на производственной площадке. Эти исключения могут быть вызваны неправильным использованием или ошибками программирования.
OutOfBounds
ИМО эффективно то, что Википедия определяет как
ответ на ваш вопрос довольно неуловим и для меня. Однако вот некоторые вещи, о которых стоит подумать:
- если массив передается, когда мы ожидаем действительный ключ массива, у нас также есть
InvalidArgumentException
потому что это не правильный тип аргумента. - мы могли бы также бросить
DomainException
потому что массивы не находятся в домене для ключей массива. - в php вы обычно не можете обнаружить типы во время компиляции из-за поздней статической привязки. Они целенаправленно задерживать привязку переменных к среде выполнения.
как я справляюсь с этой ситуацией:
- бросить
InvalidArgumentException
Если переменная передается в любую функцию, где аргумент имеет неправильный тип. Я все еще делаю это при работе с массивами. - бросить
InvalidArgumentException
Еслиnull
был передан, когда этого не должно было быть. Это действительно может быть много вещей, потому что null не набирается. Чтобы проверить код ошибки просто, я просто придерживаюсь недопустимый аргумент. - бросить
OutOfBoundsException
когда индекс не находится в правильном диапазоне, как вы и предлагали. - бросить
BadFunctionCallException
если пользовательская функция в качестве параметра не имеет правильной формы. Если ваша структура внутри массива, имеет смысл, что они могут передать функцию для ее изменения,поэтому это иногда возникает.
как правило, я могу использовать только эти три исключения для представления всех ошибок, которые происходят вне специальных ресурсы (Сетевые подключения и подключения к базе данных будут специальными ресурсами). Третий, кажется, появляется чаще, но в первую очередь я только что имел дело с первыми двумя.
Это довольно просто:
OutOfRange означает " ваш запрошенный ключ не находится в индексе набора определены в коде."
OutOfBounds означает ,что " ваш запрошенный ключ не находится в индексе набора определяется загруженной конфигурации."
путаница в этом случае исходит из нескольких факторов. Во-первых, PHP фактически скомпилирован в байт-код. Существует несколько сред выполнения, в которых эта скомпилированная форма сохраняется в относительно постоянной форме на сервере. Однако проблема OutOfRangeException/OutOfBoundsException заключается не в этом, а в ошибке категоризации, сделанной людьми, которые задокументировали эти конкретные классы исключений.
поскольку PHP динамически типизирован, часто невозможно фактически проверьте диапазоны и даже типы во время компиляции. В руководстве говорится, что OutOfRangeException должно быть вызвано во время компиляции, а OutOfBoundsException должно применяться во время выполнения, что является ошибочным различием в этом контексте.
обе ручные записи используют неясный язык того, что означает незаконный индекс, но просмотр использования их родительских классов дает некоторые подсказки: LogicExceptions расширяются классами, такими как DomainException, InvalidArgumentException и LengthException, в то время как исключения среды выполнения-это такие вещи, как UnexpectedValueException, OverflowException и UnderflowException. Из этого шаблона можно сделать вывод, что OutOfRangeException, вероятно, должно применяться к незаконным типам ключей, а OutOfBoundsException должно применяться к значениям индекса, которые имеют правильный тип, но не находятся в пределах их контейнера.
было некоторое обсуждение в списке PHP dev о том, что эти классификации ошибочны, но проблема идет глубже, чем это. На практике оба исключения могут быть вызваны только во время выполнения. Вы можете использовать капризы документации, чтобы выдавить различие между недопустимыми типами ключей и недопустимыми значениями индекса, но на данный момент мы говорим об ошибке в документации PHP.
- если вы получите неожиданный индекс. т. е. вы ожидаете
string
но в конечном итоге с помощьюinteger
или наоборот. Тогда вы должны броситьUnexpectedValueException
исключения. - если вы получаете правильный тип индекса, но его не существует. Тогда поднимите
warning
(trigger_error)
и перейти на. Это не должно остановить поток программирования. - если у вас есть объект, который является Iterable или должен быть повторяемого в диапазон и он достигает своего предела (т. е. конца файла), тогда вы должны бросить
OutOfBoundsException
. - все остальное является кандидатом на
OutOfRangeException
.
в терминах непрофессионала. Ан OutOfBoundsException
что-то нормальное. Все не так серьезно. Это то, что происходит часто и о чем следует позаботиться. он может использоваться итераторами для чтения данных до тех пор, пока не будет больше читать. Это логическая ошибка. Сделано кем-то, кто использует код не кто-то пишет код.
An OutOfRangeException
что-то серьезное. Кто-то должен посмотреть исходный код. Кто-то должен узнать, что случилось. Это важно. Теоретически этого не должно было случиться. Позвоните 911. Это ошибка времени компиляции. Сделано фиктивным программистом.
исключения из диапазона написаны программистами, чтобы защитить от ошибок других программистов. Или, может быть, себя в будущем. Если ты чувствуешь что-то подобное, то никогда не сможешь. затем используйте вне диапазона. Используйте за пределами для чего-то, что может произойти.