PHP에서 @ 연산자로 오류 억제
귀하의 의견으로는 @ 연산자를 사용하여 PHP에서 오류 / 경고를 억제하는 것이 유효한 반면 오류를 처리 할 수 있습니까?
그렇다면 어떤 상황에서 이것을 사용 하시겠습니까?
코드 예제를 환영합니다.
편집 : 회 신자 참고 사항. 오류보고 기능을 끄려는 것은 아니지만 예를 들어 일반적인 관행은
@fopen($file);
그런 다음 나중에 확인하십시오 ...하지만 다음을 수행하여 @을 제거 할 수 있습니다
if (file_exists($file))
{
fopen($file);
}
else
{
die('File not found');
}
또는 유사합니다.
질문은-@ HAS가 오류를 억제하는 데 사용되며 다른 방식으로 처리 할 수없는 곳이 있습니까?
나는 오류를 억제 하고 처리 할 것 입니다. 그렇지 않으면 TOCTOU 문제 가있을 수 있습니다 (검사 시간, 사용 시간. 예를 들어 file_exists가 true를 반환 한 후 fopen 전에 파일이 삭제 될 수 있음).
그러나 나는 오류를 없애기 위해 오류를 억제하지 않을 것입니다. 이것들은 더 잘 보입니다.
참고 : 첫째, PHP 개발자의 99 %가 오류 억제 연산자를 사용한다는 것을 알고 있습니다 (예전에는 그들 중 한 명이었습니다). 따라서이 점을 본 모든 PHP 개발자가 동의하지 않을 것으로 예상합니다.
귀하의 의견으로는 @ 연산자를 사용하여 PHP에서 오류 / 경고를 억제하는 것이 유효한 반면 오류를 처리 할 수 있습니까?
짧은 대답 :
아니요!
더 긴 정답 :
모든 것을 알지 못하기 때문에 잘 모르겠지만 지금까지 좋은 해결책 인 상황을 보지 못했습니다.
왜 나쁜지 :
PHP를 사용하는 지 약 7 년이 지난 지금 저는 오류 억제 연산자로 인한 끝없는 디버깅 고뇌를 보았고 피할 수없는 상황에 직면 한 적이 없습니다.
문제는 오류를 억제하는 코드 조각이 현재보고있는 오류 만 일으킬 수 있다는 것입니다. 그러나 억제 된 라인이 의존하는 코드 또는 실행되는 환경을 변경하면 라인이 무시하려는 것과 완전히 다른 오류를 출력하려고 시도 할 가능성이 있습니다. 그러면 출력되지 않는 오류를 어떻게 추적합니까? 지옥 디버깅에 오신 것을 환영합니다!
억제 된 오류 때문에 몇 달마다 얼마나 많은 시간을 낭비하고 있는지 깨닫는 데 수년이 걸렸습니다. 대부분의 경우 (단독적으로는 아님) 개발자 환경에서 오류가없는 타사 스크립트 / 앱 / 라이브러리를 설치 한 후 였지만 PHP 또는 서버 구성 차이 또는 일반적으로 오류를 즉시 출력하는 종속성 누락으로 인해 내 것이 아닙니다. 문제가 무엇인지 경고하지만 개발자가 마법 @을 추가 할 때가 아닙니다.
대안 (상황 및 원하는 결과에 따라 다름) :
알고있는 실제 오류를 처리하여 코드 조각이 특정 오류를 유발할 경우 해당 특정 상황에서 실행되지 않도록합니다. 하지만이 부분을 이해하고 최종 사용자에게 오류가 표시되는 것에 대해 걱정 한 것 같습니다.
일반적인 오류의 경우 페이지를 볼 때 원하는 방식으로 출력되도록 오류 처리기를 설정할 수 있지만 최종 사용자에게는 숨겨지고 기록되므로 사용자가 어떤 오류를 유발하는지 알 수 있습니다.
치명적인 오류 display_errors의 경우 php.ini에서 off로 설정 하고 (오류 처리기가 여전히 트리거 됨) 오류 로깅을 활성화합니다. 개발 서버와 라이브 서버 (내가 권장하는)가있는 경우 개발 서버에서이 단계가 필요하지 않으므로 오류 로그 파일을 확인하지 않고도 이러한 치명적인 오류를 디버깅 할 수 있습니다. 종료 함수 를 사용 하여 오류 처리기에 많은 치명적인 오류를 보내는 트릭 도 있습니다 .
요약 :
그것을 피하십시오. 그럴만 한 이유가 있을지 모르지만 아직 하나를 보지 못했기 때문에 그날까지 (@) 오류 억제 연산자가 악하다고 생각합니다.
더 많은 정보를 원하면 PHP 매뉴얼 의 오류 제어 연산자 페이지 에서 내 의견을 읽을 수 있습니다 .
예, 억제는 의미가 있습니다.
예를 들어, 파일을 열 수없는 경우 fopen()명령이 반환 FALSE됩니다. 괜찮지 만 PHP 경고 메시지 도 생성합니다. 경고를 원하지 않는 경우가 FALSE많습니다. 직접 확인해야합니다 .
실제로 PHP 매뉴얼 은이 경우 @ 사용을 구체적으로 제안합니다!
fopen ()과 같은 함수를 사용할 때 경고가 발생하지 않도록하려면 오류를 억제하지만 예외를 사용할 수 있습니다.
try {
if (($fp = @fopen($filename, "r")) == false) {
throw new Exception;
} else {
do_file_stuff();
}
} catch (Exception $e) {
handle_exception();
}
나는 절대로 '@'... 마침표를 사용하는 것을 허용하지 않습니다.
코드에서 '@'의 사용을 발견하면 사용 시점과 사용되는 함수 주변의 docblock에 주석을 추가하여 눈에 띄게 명확하게 만듭니다. 저도 이런 종류의 오류 억제로 인해 "유령을 쫓는"디버깅에 물 렸으며, 발견했을 때 그 사용법을 강조하여 다음 사람이 더 쉽게 사용할 수 있기를 바랍니다.
네이티브 PHP 함수에 오류가 발생하고 '@'가 쉬운 방법 인 경우 내 코드에서 Exception을 던지기를 원하는 경우 대신 동일한 결과를 얻지 만 다른 작업을 수행하도록 선택합니다. (다시) 코드에서 눈에 띄게 분명합니다.
$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();
그러나 나는 나를 따르는 불쌍한 디버깅 영혼을 위해 내 억제가 매우 분명하게 필요하게 만드는 것을 선호합니다.
모든 조건을 처리 할 수 있다는 것을 알지 못하는 경우 오류 억제는 피해야 합니다.
이것은 처음 보는 것보다 훨씬 어려울 수 있습니다.
실제로해야 할 일은 php의 "error_log"를보고 방법으로 사용하는 것입니다. 사용자가 페이지를보고 오류를보고하는 데 의존 할 수 없기 때문입니다. (그리고 당신은 또한 이러한 오류를 표시하는 php를 비활성화해야합니다)
그러면 적어도 시스템에서 잘못되는 모든 일에 대한 포괄적 인 보고서를 받게됩니다.
정말로 오류를 처리해야하는 경우 사용자 지정 오류 처리기를 만들 수 있습니다.
http://php.net/set-error-handler
그런 다음 예외를 보낼 수 있고 (처리 할 수 있음) 이상한 오류를 관리에보고하는 데 필요한 모든 작업을 수행 할 수 있습니다.
대부분의 사람들은 오류 메시지의 의미를 이해하지 못합니다.
농담이 아닙니다. 그들 중 대부분.
그들은 오류 메시지가 모두 동일하다고 생각하며 "뭔가 잘못되었습니다!"라고 말합니다.
그들은 그것을 읽는 것을 귀찮게하지 않습니다.
오류 메시지의 가장 중요한 부분이지만, 제기 된 사실뿐만 아니라 의미이기도합니다. 무엇이 잘못되었는지 알려줄 수 있습니다 . 오류 메시지는 "숨기는 방법"으로 귀찮게하는 것이 아니라 도움을위한 것입니다. 문제. 이것은 초보자 웹 프로그래밍 세계에서 가장 큰 오해 중 하나입니다.
따라서 개깅 오류 메시지 대신 그 내용을 읽어야 합니다. "파일을 찾을 수 없음"값이 하나만있는 것은 아닙니다. permission denied, save mode restriction등 수천 가지 오류가있을 수 있습니다 open_basedir restriction. 각각 적절한 조치가 필요합니다. 하지만 개그를 치면 무슨 일이 일어 났는지 결코 알 수 없습니다!
The OP is messing up error reporting with error handling, while it's very big difference!
Error handling is for user. "something happened" is enough here.
While error reporting is for programmer, who desperately need to know what certainly happened.
Thus, never gag errors messages. Both log it for the programmer, and handle it for the user.
is there not a way to suppress from the php.ini warnings and errors? in that case you can debug only changing a flag and not trying to discovering which @ is hiding the problem.
Using @ is sometimes counter productive. In my experience, you should always turn error reporting off in the php.ini or call
error_reporting(0);
on a production site. This way when you are in development you can just comment out the line and keep errors visible for debugging.
The only place where I really needed to use it is the eval function. The problem with eval is that, when string cannot be parsed due to syntax error, eval does not return false, but rather throws an error, just like having a parse error in the regular script. In order to check whether the script stored in the string is parseable you can use something like:
$script_ok = @eval('return true; '.$script);
AFAIK, this is the most elegant way to do this.
One place I use it is in socket code, for example, if you have a timeout set you'll get a warning on this if you don't include @, even though it's valid to not get a packet.
$data_len = @socket_recvfrom( $sock, $buffer, 512, 0, $remote_host, $remote_port )
You do not want to suppress everything, since it slows down your script.
And yes there is a way both in php.ini and within your script to remove errors (but only do this when you are in a live environment and log your errors from php)
<?php
error_reporting(0);
?>
And you can read this for the php.ini version of turning it off.
Today I encountered an issue that was a good example on when one might want to use at least temporarily the @ operator.
Long story made short, I found logon info (username and password in plain text) written into the error log trace.
Here a bit more info about this issue.
The logon logic is in a class of it's own, because the system is supposed to offer different logon mechanisms. Due to server migration issues there was an error occurring. That error dumped the entire trace into the error log, including password info! One method expected the username and password as parameters, hence trace wrote everything faithfully into the error log.
The long term fix here is to refactor said class, instead of using username and password as 2 parameters, for example using a single array parameter containing those 2 values (trace will write out Array for the paramater in such cases). There are also other ways of tackling this issue, but that is an entire different issue.
Anyways. Trace messages are helpful, but in this case were outright harmful.
The lesson I learned, as soon as I noticed that trace output: Sometimes suppressing an error message for the time being is an useful stop gap measure to avoid further harm.
In my opinion I didn't think it is a case of bad class design. The error itself was triggered by an PDOException ( timestamp issue moving from MySQL 5.6 to 5.7 ) that just dumped by PHP default everything into the error log.
In general I do not use the @ operator for all the reasons explained in other comments, but in this case the error log convinced me to do something quick until the problem was properly fixed.
If you are using a custom error handling function and wanna suppress an error (probably a known error), use this method. The use of '@' is not a good idea in this context as it will not suppress error if error handler is set.
Write 3 functions and call like this.
# 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
}
I use it when trying to load an HTML file for processing as a DOMDocument object. If there are any problems in the HTML... and what website doesn't have at least one... DOMDocument->loadHTMLFile() will throw an error if you don't suppress it with @. This is the only way (perhaps there are better ones) I've ever been successful in creating HTML scrapers in PHP.
참고URL : https://stackoverflow.com/questions/136899/suppress-error-with-operator-in-php
'Nice programing' 카테고리의 다른 글
| 동적으로 활동 이름 가져 오기-Android (0) | 2020.11.09 |
|---|---|
| 개체를 HttpClient.PostAsync에 전달하고 JSON 본문으로 직렬화하려면 어떻게해야합니까? (0) | 2020.11.09 |
| Mac OSX에 Matplotlib 플롯이 표시되지 않습니까? (0) | 2020.11.09 |
| xcode 4에 내 코드 조각을 추가 할 수 있습니까? (0) | 2020.11.09 |
| 정규식 아님 연산자 (0) | 2020.11.09 |