Это означает, что ваш код использовал ссылочную переменную объекта, которая была установлена в нуль (т. е. она не ссылалась на экземпляр фактического объекта).
Чтобы предотвратить ошибку, объекты, которые могут быть пустыми, должны быть протестированы для null перед тем, как использовать.
if (myvar != null)
{
// Go ahead and use myvar
myvar.property = ...
}
else
{
// Whoops! myvar is null and cannot be used without first
// assigning it to an instance reference
// Attempting to use myvar here will result in NullReferenceException
}
Я бы подавил ошибку и обработал ее. В противном случае у вас может быть проблема с TOCTOU (время проверки, время использования. Например, файл может быть удален после того, как file_exists вернет true, но до fopen).
Но я бы не просто подавлять ошибки, чтобы заставить их уйти. Это лучше видно.
Вы не хотите подавлять все, так как это замедляет ваш скрипт.
И да, есть способ как в php.ini, так и внутри вашего скрипта удалить ошибки (но делать это только тогда, когда вы находятся в живой среде и записывают ваши ошибки из php)
<?php
error_reporting(0);
?>
И вы можете прочитать это для версии php.ini, отключив ее.
Если вы используете пользовательскую функцию обработки ошибок и хотите подавить ошибку (возможно, известную ошибку), используйте этот метод. Использование «@» не является хорошей идеей в этом контексте, поскольку оно не будет подавлять ошибку, если установлен обработчик ошибок.
Напишите 3 функции и вызовите это.
# supress error for this statement
supress_error_start();
$mail_sent = mail($EmailTo, $Subject, $message,$headers);
supress_error_end(); #Don't forgot to call this to restore error.
function supress_error_start(){
set_error_handler('nothing');
error_reporting(0);
}
function supress_error_end(){
set_error_handler('my_err_handler');
error_reporting('Set this to a value of your choice');
}
function nothing(){ #Empty function
}
function my_err_handler('arguments will come here'){
//Your own error handling routines will come here
}
Я НИКОГДА не позволяю себе использовать «@» ... период.
Когда я обнаруживаю использование «@» в коде, я добавляю комментарии, чтобы сделать его очевидным, как в момент использования , и в док-блоке вокруг функции, в которой он используется. Я тоже был укушен отладкой «преследовать призрак» из-за такого подавления ошибок, и я надеюсь облегчить его следующее, выделив его использование, когда я его найду.
В тех случаях, когда Я хочу, чтобы мой собственный код выдавал исключение, если встроенная функция PHP обнаруживает ошибку, а «@» - это простой способ, я вместо этого хочу сделать что-то другое, получающее тот же результат, но (снова) явственно видно в коде:
$orig = error_reporting(); // capture original error level
error_reporting(0); // suppress all errors
$result = native_func(); // native_func() is expected to return FALSE when it errors
error_reporting($orig); // restore error reporting to its original level
if (false === $result) { throw new Exception('native_func() failed'); }
Это намного больше кода, который просто пишет:
$result = @native_func();
, но я предпочитаю, чтобы мое подавление требовало ОЧЕНЬ ОБЫЧНОГО, ради бедная отладочная душа, которая следует за мной.
Если вы не хотите вызывать предупреждение при использовании таких функций, как fopen (), вы можете подавить ошибку, но использовать исключения:
try {
if (($fp = @fopen($filename, "r")) == false) {
throw new Exception;
} else {
do_file_stuff();
}
} catch (Exception $e) {
handle_exception();
}
else
, просто do_file_stuff()
.
– MrWhite
21 January 2014 в 18:08
Одно место, которое я использую, это код сокета, например, если у вас установлен тайм-аут, вы получите предупреждение об этом, если вы не включите @, даже если оно действительно не для получения пакета.
$data_len = @socket_recvfrom( $sock, $buffer, 512, 0, $remote_host, $remote_port )
нет способа подавить предупреждения и ошибки php.ini? в этом случае вы можете отлаживать только изменение флага и не пытаться обнаружить, что @ скрывает проблему.
Использование @ иногда является результативным. По моему опыту, вы всегда должны отключать отчет об ошибках в php.ini или вызывать
error_reporting(0);
на производственной площадке. Таким образом, когда вы находитесь в разработке, вы можете просто прокомментировать строку и сохранить видимые ошибки для отладки.
ini_set('display_errors',0);
или еще лучше, напрямую изменить INI-файл, чтобы включить это.
– Chinoto Vokro
26 February 2016 в 18:41
Примечание: во-первых, я понимаю, что 99% разработчиков PHP используют оператор подавления ошибок (я был одним из них), поэтому я ожидаю, что любой PHP-разработчик увидит, что это не согласуется.
Как вы считаете, действительно ли действительно использовать оператор @ для подавления ошибки / предупреждения в PHP, тогда как вы можете обрабатывать ошибку?
Краткий ответ: Нет!
Более правильный ответ: я не знаю, поскольку я не знаю всего, но пока что я не сталкивался с ситуацией, когда это было хорошим решением.
Почему это Плохо: в том, что я думаю, около 7 лет с использованием PHP теперь я видел бесконечную агонию отладки, вызванную оператором подавления ошибок, и никогда не сталкивался с ситуацией, когда это было неизбежно.
Проблема в том, что кусок кода, с которым вы подавляете ошибки, в настоящее время может вызывать только ошибку, которую вы видите; однако, когда вы меняете код, на который полагается подавленная линия, или среда, в которой она выполняется, тогда есть все шансы, что линия попытается вывести совершенно другую ошибку из той, которую вы пытались игнорировать. Тогда как вы отслеживаете ошибку, которая не выводится? Добро пожаловать в отладку ада!
Мне потребовалось много лет, чтобы понять, сколько времени я трачу каждые пару месяцев из-за подавленных ошибок. Чаще всего (но не исключительно) это было после установки стороннего скрипта / приложения / библиотеки, которая была безошибочной в среде разработчиков, но не моя из-за разницы в конфигурации сервера или сервера или отсутствовала зависимость, которая могла бы нормально вывести ошибку немедленно предупреждая о проблеме, но не тогда, когда разработчик добавляет magic @.
Альтернативы (в зависимости от ситуации и желаемого результата): обрабатывайте фактическую ошибку, о которой вы знаете, так что, если часть кода вызовет определенную ошибку, тогда он не будет запущен в этой конкретной ситуации. Но я думаю, что вы получаете эту часть, и вы просто беспокоились о том, что конечные пользователи видят ошибки, и это то, что я сейчас адресую.
Для регулярных ошибок вы можете настроить обработчик ошибок, чтобы они выводились в который вам нужен, когда вы просматриваете страницу, но скрыты от конечных пользователей и регистрируетесь, чтобы вы знали, какие ошибки запускают ваши пользователи.
Для фатальных ошибок установите
display_errors
в выключенном состоянии (ваш обработчик ошибок все еще получает ) в вашем php.ini и включить ведение журнала ошибок. Если у вас есть сервер разработки, а также живой сервер (который я рекомендую), этот шаг не требуется на вашем сервере разработки, поэтому вы можете отлаживать эти фатальные ошибки, не прибегая к просмотру файла журнала ошибок. Существует даже трюк , использующий функцию выключения , чтобы отправить большое количество фатальных ошибок вашему обработчику ошибок.Вкратце: пожалуйста, избегайте этого. Для этого может быть веская причина, но я еще не видел ее, поэтому до сих пор я считаю, что оператор подавления ошибок (@) является злым.
Вы можете прочитать мой комментарий к странице «Операторы контроля ошибок» в руководстве по PHP, если вы хотите получить дополнительную информацию.
-1
для поглаживания глупых "является злым" мем. Исключение встроенной языковой функции с явным пренебрежением к фактическому варианту использования - это основное определение программирования культовых грузов. - В частности, в этом заявлении не упоминается, что подавленные ошибки фактически не исчезли. Пользовательский обработчик ошибок может все еще оживить их (set_error_handler("var_dump");
- ленивый эквивалент расширения крика). Более того, такие чрезмерные советы приводят к обычным обходным синтаксическим синтаксическим искажениям isset()
, которые фактически могут препятствовать отладке (поскольку отладочные уведомления затем подавляются безвозвратно).
– mario
24 October 2011 в 15:57
Да, подавление имеет смысл.
Например, команда fopen()
возвращает FALSE
, если файл не может быть открыт. Это нормально, но также создает предупреждающее сообщение PHP. Часто вы не хотите предупреждения - вы сами проверите FALSE
.
На самом деле руководство по PHP специально предлагает использовать @ в этом случае!
Следует избегать подавления ошибок, если вы не знаете , что вы можете обрабатывать все условия.
Это может быть намного сложнее, чем кажется на первый взгляд.
То, что вам действительно нужно, это полагаться на «error_log» php, чтобы быть вашим методом отчетности, так как вы не можете полагаться на просмотр пользователями страниц, чтобы сообщать об ошибках. (И вы также должны отключить php от отображения этих ошибок)
Тогда, по крайней мере, у вас будет исчерпывающий отчет о том, что все происходит неправильно в системе.
Если вы действительно должны обрабатывать ошибки, вы можете создать собственный обработчик ошибок
http://php.net/set-error-handler
Тогда вы можете отправить исключения (которые могут быть обработаны) и сделать все, что необходимо для сообщения о странных ошибках для администрирования.
Единственное место, где мне действительно нужно было использовать его, - это функция eval. Проблема с eval заключается в том, что, когда строка не может быть проанализирована из-за ошибки синтаксиса, eval не возвращает false, а скорее выдает ошибку, точно так же, как наличие ошибки синтаксического анализа в регулярном скрипте. Чтобы проверить, является ли скрипт, хранящийся в строке, синтаксическим, вы можете использовать что-то вроде:
$script_ok = @eval('return true; '.$script);
AFAIK, это самый элегантный способ сделать это.
Я использую его при попытке загрузить HTML-файл для обработки в качестве объекта DOMDocument. Если в HTML есть какие-либо проблемы ... и на каком веб-сайте нет хотя бы один ... DOMDocument-> loadHTMLFile () выдает ошибку, если вы не подавите ее с помощью @ , Это единственный способ (возможно, лучшие). Мне когда-либо удавалось создавать HTML-скребки в PHP.
Большинство людей не понимают значения сообщения об ошибке. Без шуток. Большинство из них.
Они считают, что сообщения об ошибках одинаковы, говорит: «Что-то не так!» Они не удосужились его прочитать. Хотя это самая важная часть сообщения об ошибке, а не только тот факт, что она была поднята, но это имеет значение. Это может сказать вам , что идет не так. Сообщения об ошибках предназначены для помощи, а не для того, чтобы беспокоить вас «как скрыть это?». проблема. Это одно из самых больших недоразумений в мире веб-программирования новичка.
Таким образом, вместо сообщения об ошибке gagging следует прочитать то, что он говорит. Он имеет не только одно значение «файл не найден». Могут быть тысячи разных ошибок: permission denied
, save mode restriction
, open_basedir restriction
и т. Д. Каждый из них требует соответствующих действий. Но если вы заткнете это, вы никогда не узнаете, что произошло!
OP представляет собой сообщение об ошибках с обработкой ошибок, в то время как это очень большая разница! Обработка ошибок для пользователя. «что-то случилось» достаточно. Хотя сообщения об ошибках предназначены для программистов, которым отчаянно нужно знать, что именно произошло.
Таким образом, сообщения о ошибках никогда не появляются. Оба регистрируют его для программиста и обрабатывают его для пользователя.