복붙노트

경고를 시도 할 수 있습니까?

PHP

경고를 시도 할 수 있습니까?

몇 가지 경고를 일부 PHP 네이티브 함수에서 던져되고 잡을 필요가 그들을 처리 할 수 ​​있습니다.

구체적으로 :

array dns_get_record  ( string $hostname  [, int $type= DNS_ANY  [, array &$authns  [, array &$addtl  ]]] )

DNS 쿼리가 실패하면 경고가 발생합니다.

try / catch는 경고가 예외가 아니기 때문에 작동하지 않습니다.

이제 2 가지 옵션이 있습니다.

가장 좋은 방법은 무엇입니까?

해결법

  1. ==============================

    1.오류 처리기 설정 및 복원

    오류 처리기 설정 및 복원

    한 가지 가능성은 호출 전에 자체 오류 처리기를 설정하고 나중에 restore_error_handler ()를 사용하여 이전 오류 처리기를 복원하는 것입니다.

    set_error_handler(function() { /* ignore errors */ });
    dns_get_record();
    restore_error_handler();
    

    이 아이디어를 바탕으로 오류를 기록하는 재사용 가능한 오류 처리기를 작성할 수 있습니다.

    set_error_handler([$logger, 'onSilencedError']);
    dns_get_record();
    restore_error_handler();
    

    오류를 예외로 변환

    set_error_handler () 및 ErrorException 클래스를 사용하여 모든 PHP 오류를 예외로 설정할 수 있습니다.

    set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) {
        // error was suppressed with the @-operator
        if (0 === error_reporting()) {
            return false;
        }
    
        throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
    });
    
    try {
        dns_get_record();
    } catch (ErrorException $e) {
        // ...
    }
    

    자체 오류 처리기를 사용할 때주의해야 할 중요한 점은 error_reporting 설정을 무시하고 모든 오류 (주의 사항, 경고 등)를 오류 처리기로 전달한다는 것입니다. set_error_handler ()에서 두 번째 인수를 설정하여 수신 할 오류 유형을 정의하거나 오류 처리기에서 ... = error_reporting ()을 사용하여 현재 설정에 액세스 할 수 있습니다.

    경고 표시 안 함

    또 다른 방법은 @ 연산자를 사용하여 호출을 억제하고 나중에 dns_get_record ()의 반환 값을 확인하는 것입니다. 그러나 나는 오류 / 경고가 억제되도록 처리되지 않도록 트리거되도록 권고하고 있습니다.

  2. ==============================

    2.정말 작동하는 솔루션은 E_WARNING 매개 변수를 사용하여 간단한 오류 처리기를 설정하는 것으로 밝혀졌습니다.

    정말 작동하는 솔루션은 E_WARNING 매개 변수를 사용하여 간단한 오류 처리기를 설정하는 것으로 밝혀졌습니다.

    set_error_handler("warning_handler", E_WARNING);
    dns_get_record(...)
    restore_error_handler();
    
    function warning_handler($errno, $errstr) { 
    // do something
    }
    
  3. ==============================

    3.@ 연산자를주의 깊게 읽으십시오 - 경고를 억제하는 동시에 치명적인 오류를 억제하십시오. 누군가가 @mysql_query ( '...')를 작성한 시스템에서 문제를 디버깅하는 데 많은 시간을 보냈으며 문제는 mysql 지원이 PHP에로드되지 않고 조용한 치명적인 오류가 발생한다는 것입니다. PHP 코어에 포함 된 것들은 안전 할 것이나주의해서 사용하십시오.

    @ 연산자를주의 깊게 읽으십시오 - 경고를 억제하는 동시에 치명적인 오류를 억제하십시오. 누군가가 @mysql_query ( '...')를 작성한 시스템에서 문제를 디버깅하는 데 많은 시간을 보냈으며 문제는 mysql 지원이 PHP에로드되지 않고 조용한 치명적인 오류가 발생한다는 것입니다. PHP 코어에 포함 된 것들은 안전 할 것이나주의해서 사용하십시오.

    bob@mypc:~$ php -a
    Interactive shell
    
    php > echo @something(); // this will just silently die...
    

    더 이상의 출력이 없습니다 - 행운을 빌어 요!

    bob@mypc:~$ php -a
    Interactive shell
    
    php > echo something(); // lets try it again but don't suppress the error
    PHP Fatal error:  Call to undefined function something() in php shell code on line 1
    PHP Stack trace:
    PHP   1. {main}() php shell code:0
    bob@mypc:~$ 
    

    이번에는 실패한 이유를 알 수 있습니다.

  4. ==============================

    4.경고를 표시하려고했지만 동시에 경고 / 오류 로깅을 유지합니다 (예 : /var/log/apache2/error.log). 핸들러는 false를 반환해야합니다. 그러나 "throw new ..."문은 기본적으로 실행을 중단하므로 하나의 함수에서 "wrap in function"트릭을 수행해야합니다.

    경고를 표시하려고했지만 동시에 경고 / 오류 로깅을 유지합니다 (예 : /var/log/apache2/error.log). 핸들러는 false를 반환해야합니다. 그러나 "throw new ..."문은 기본적으로 실행을 중단하므로 하나의 함수에서 "wrap in function"트릭을 수행해야합니다.

    PHP에서 예외를 던질 정적 방법이 있나요?

    또는 간단히 :

      function throwErrorException($errstr = null,$code = null, $errno = null, $errfile = null, $errline = null) {
        throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
      }
      function warning_handler($errno, $errstr, $errfile, $errline, array $errcontext) {
        return false && throwErrorException($errstr, 0, $errno, $errfile, $errline);
        # error_log("AAA"); # will never run after throw
        /* Do execute PHP internal error handler */
        # return false; # will never run after throw
      }
      ...
      set_error_handler('warning_handler', E_WARNING);
      ...
      try {
        mkdir($path, 0777, true);
      } catch (Exception $e) {
        echo $e->getMessage();
        // ...
      }
    

    편집 : 면밀한 검사 후, 그것은 작동하지 않는 것으로 밝혀졌습니다 : "return false && throwErrorException ..."기본적으로, 예외를 throw하지 않으며 단지 오류 로그에 로그인; "return throwErrorException ..."에서와 같이 "false &&"부분을 제거하면 예외가 발생하지만 error_log에 로그인하지 않습니다 ... 여전히 게시 된 상태로 유지됩니다. 다른 곳에 문서화 된이 행동을 보지 못했습니다.

  5. ==============================

    5.아마도 경고를 완전히 없애려고 시도해야하지만 가능하지 않다면 @ (즉 @dns_get_record (...))를 호출 한 다음 경고가 발생한 경우 알아낼 수있는 정보를 사용하십시오 아닙니다.

    아마도 경고를 완전히 없애려고 시도해야하지만 가능하지 않다면 @ (즉 @dns_get_record (...))를 호출 한 다음 경고가 발생한 경우 알아낼 수있는 정보를 사용하십시오 아닙니다.

  6. ==============================

    6.이 솔루션이 유일한 해결책이 아니라면 일반적으로 @를 사용하지 않아야합니다. 이 경우 레코드가 존재 하는지를 알기 위해서는 dns_check_record 함수가 먼저 사용되어야합니다.

    이 솔루션이 유일한 해결책이 아니라면 일반적으로 @를 사용하지 않아야합니다. 이 경우 레코드가 존재 하는지를 알기 위해서는 dns_check_record 함수가 먼저 사용되어야합니다.

  7. ==============================

    7.dns_get_record ()가 실패하면 FALSE를 반환하므로 @로 경고를 표시하지 않고 반환 값을 확인할 수 있습니다.

    dns_get_record ()가 실패하면 FALSE를 반환하므로 @로 경고를 표시하지 않고 반환 값을 확인할 수 있습니다.

  8. ==============================

    8.외부 URL에 대한 file_get_contents () 호출을 통해 이러한 코드를 결합하면 "열지 못했습니다 : 연결 시간 초과"와 같은 경고를 처리하는 데 도움이되었습니다.

    외부 URL에 대한 file_get_contents () 호출을 통해 이러한 코드를 결합하면 "열지 못했습니다 : 연결 시간 초과"와 같은 경고를 처리하는 데 도움이되었습니다.

    set_error_handler(function ($err_severity, $err_msg, $err_file, $err_line, array $err_context)
    {
        throw new ErrorException( $err_msg, 0, $err_severity, $err_file, $err_line );
    }, E_WARNING);
    try {
        $iResult = file_get_contents($sUrl);
    } catch (Exception $e) {
        $this->sErrorMsg = $e->getMessage();
    }
    restore_error_handler();
    

    이 솔루션은 객체 컨텍스트 내에서도 작동합니다. 함수에서 사용할 수 있습니다.

    public function myContentGetter($sUrl)
    {
      ... code above ...
      return $iResult;
    }
    
  9. ==============================

    9.부울 값을 반환하는지 확인한 다음 조건으로 간단히 넣을 수 있습니다. 내 고유 키를 사용하여 일부 위반을 반환하는 oci_execute (...)와 함께이 문제가 발생했습니다.

    부울 값을 반환하는지 확인한 다음 조건으로 간단히 넣을 수 있습니다. 내 고유 키를 사용하여 일부 위반을 반환하는 oci_execute (...)와 함께이 문제가 발생했습니다.

    ex.
    oci_parse($res, "[oracle pl/sql]");
    if(oci_execute){
    ...do something
    }
    
  10. ==============================

    10.직선적 인 조작 (예 : $ prop = @ ($ high / ($ width - $ depth)) 일 때 경고를 표시하지 않으려면 @를 사용하고 0 경고로 나누기를 건너 뛰는 것만 권장합니다. 그러나 대부분의 경우 처리하는 것이 좋습니다.

    직선적 인 조작 (예 : $ prop = @ ($ high / ($ width - $ depth)) 일 때 경고를 표시하지 않으려면 @를 사용하고 0 경고로 나누기를 건너 뛰는 것만 권장합니다. 그러나 대부분의 경우 처리하는 것이 좋습니다.

  11. from https://stackoverflow.com/questions/1241728/can-i-try-catch-a-warning by cc-by-sa and MIT license