происходит с кодом, подобным xyz->method()
, где xyz
не является объектом и, следовательно, method
не может
Это фатальная ошибка, которая остановит сценарий (уведомление о прямой совместимости: это станет захватывающей ошибкой, начиная с PHP 7).
Чаще всего это знак что в коде отсутствуют проверки условий ошибок. Убедитесь, что объект фактически является объектом перед вызовом его методов.
Пример типичного будет
// ... some code using PDO
$statement = $pdo->prepare('invalid query', ...);
$statement->execute(...);
В приведенном выше примере запрос не может и prepare()
назначит false
на $statement
. Попытка вызвать метод execute()
приведет к Fatal Error, потому что false
является «не объектом», потому что значение является логическим.
Выясните , почему ваша функция вернула логическое значение вместо объекта. Например, проверьте объект $pdo
для последней произошедшей ошибки. Подробности о том, как отлаживать это, будут зависеть от того, как обрабатываются ошибки для конкретной рассматриваемой функции / объекта / класса.
Если даже сбой ->prepare
не выполняется, то ваш дескриптор
// ... some code using PDO
$statement = $pdo->prepare('invalid query', ...);
$statement->execute(...);
базы данных
// ... some code using PDO
$statement = $pdo->prepare('invalid query', ...);
$statement->execute(...);
не попал в текущий объем . Найдите, где он определился. Затем передайте его как параметр, сохраните его как свойство или поделите его через глобальную область.
Другой проблемой может быть условное создание объекта, а затем попытка вызова метода вне этого условного блока. Например,
if ($someCondition) {
$myObj = new MyObj();
}
// ...
$myObj->someMethod();
Пытаясь выполнить метод вне условного блока, ваш объект не может быть определен.
Вопросы, относящиеся:
Лично, и я думаю, что это сохранено условно, EAFP никогда не является хорошим способом пойти. Можно посмотреть на него как на эквивалент следующему:
if (o != null)
o.doSomething();
else
// handle
в противоположность:
try {
o.doSomething()
}
catch (NullPointerException npe) {
// handle
}
, Кроме того, рассмотрите следующее:
if (a != null)
if (b != null)
if (c != null)
a.getB().getC().doSomething();
else
// handle c null
else
// handle b null
else
// handle a null
Это может выглядеть намного менее изящным (и да это - сырой пример - терпят меня), но он дает Вам намного большую гранулярность в обработке ошибки, в противоположность обертыванию всего этого в выгоде попытки, чтобы получить это NullPointerException
, и затем попытаться выяснить, где и почему Вы получили его.
способ, которым я вижу его EAFP, никогда не должен использоваться, за исключением редких ситуаций. Кроме того, так как Вы подняли вопрос: да, блок try-catch действительно подвергается немного служебным , даже если исключение не выдается.
При доступе к файлам EAFP более надежен, чем LBYL, потому что операции, вовлеченные в LBYL, не являются атомарными, и файловая система могла бы измениться между временем, Вы смотрите и время, Вы прыгаете. На самом деле стандартное имя является TOCTOU - Время Проверки, Время Использования; ошибки, вызванные неточной проверкой, являются ошибками TOCTOU.
Рассматривают создание временного файла, который должен иметь уникальное имя. Лучший способ узнать, существует ли выбранное имя файла уже, состоит в том, чтобы попытаться создать его - проверка, что Вы используете опции гарантировать, что Ваша операция перестала работать, если файл действительно уже существует (в терминах POSIX/Unix, флаге O_EXCL к open()
). При попытке протестировать, существует ли файл уже (вероятно, использование access()
), то между временем, когда это говорит "Нет" и время, Вы пытаетесь создать файл, кого-то, или что-то еще, возможно, создало файл.
С другой стороны, предположите, что Вы пытаетесь считать существующий файл. Ваша проверка, что файл существует (LBYL), может сказать, что "это там", но когда Вы на самом деле открываете его, Вы находите, что "это не там".
и В этих случаях, необходимо проверить заключительную операцию - и в LBYL, автоматически не помог.
(Если Вы смешиваете с SUID или программами SGID, access()
, задает различный вопрос; это может относиться к LBYL, но код все еще должен принять во внимание возможность отказа.)
В дополнение к относительной стоимости исключений в Python и Java, имейте в виду, что существует различие в философии / отношение между ними. Java пытается быть очень строгим о типах (и все остальное), требуя явных, подробных объявлений класса/сигнатур методов. Это предполагает, что необходимо знать в любой точке, точно какой объект Вы используете и что это способно к выполнению. Напротив, "утиный ввод Python" означает, что Вы не знаете наверняка (и не должен заботиться), каков явный тип объекта, только необходимо заботиться, что это шарлатаны, когда Вы спрашиваете его к. В этом виде общества вседозволенности единственное нормальное отношение должно предположить, что вещи будут работать, но будут готовы иметь дело с последствиями, если они не сделают. Java, естественный строгий, не соответствует хорошо такому случайному подходу. (Это не предназначается, чтобы осуждать или подход или язык, а скорее сказать, что эти отношения являются частью идиомы каждого языка, и копирование идиом между различными языками может часто приводить к неловкости и плохой связи...)
Исключения обработаны более эффективно в Python, чем в Java, который является [по крайней мере 110] частично , почему Вы видите ту конструкцию в Python. В Java это более неэффективно (с точки зрения производительности) для использования исключений таким образом.