PHP 이상 처리라고 하면, 여러분은 try-catch를 먼저 생각할 것입니다. 자, 먼저 프로그램을 봅시다: test.php 파일이 있고, 간단한 PHP 프로그램이 있습니다. 내용은 다음과 같습니다. 그리고 나서 명령줄을 실행합니다: phptest.php
1 <?php
2 $num = 0;
3 try {
4 echo 1/$num;
5
6 } catch (Exception $e){
7 echo $e->getMessage();
8 }
9 ?>
제 질문은: 이 프로그램이 0을 제거하는 오류 메시지를 정확하게 포착할 수 있습니까?
만약 당신이 할 수 있다고 대답한다면, 당신은 이 문장을 다 읽으세요!뭔가 배울 수 있을 것 같아.
이 장에서는 다섯 부분으로 나누어 나의 이상 처리에 대한 이해를 소개한다.
1. 이상과 오류의 개요
둘, ERROR의 클래스
3. PHP 이상 처리의 블랙 테크놀로지
4.교묘하게 오류와 이상을 포착
5. 사용자 정의 예외 처리 및 예외 중첩
6. PHP7에서의 이상 처리
1. 이상과 오류의 개요
PHP이상이란 무엇입니까?
프로그램이 실행 중인지 여부예상에 맞는 상황, 허용 (너도 그를 내보내지 않을 거야)현재 비정상적인 상황) 그러나 그는 비정상적인 상황입니다. 우리의 정상적인 논리에 따라서는 안 될 오류입니다. 그러나 여전히 발생할 수 있는 오류는 논리 및 업무 프로세스의 오류입니다. 컴파일이나 문법상의 오류가 아닙니다.
PHP에서 오류란 무엇입니까?:
php 스크립트 자체에 속함문제는, 대부분의 경우 잘못된 문법, 서버가환경으로 인해 컴파일러가 검사를 통과하지 못하거나 심지어 실행할 수 없는 상황입니다.워닝, 노티스는 모두 오류인데 급이 다를 뿐이고, 트라이캐치에 오류가 잡히면 안 된다.
위의 설은 전제가 있다조건:
PHP에서 왜냐하면다른 언어에서는 이렇게 결론을 내릴 수 없다.흔히 틀린 설과 다른 언어에서 다른 설이 있다.PHP에서는 어떤 자체 오류나 비정상적인 코드도 버그로 취급하고 비정상적인 형태로 던지지 않지만, 이상과 버그가 동시에 던져지는 경우도 있다(적절한 예를 찾지 못했다고 한다).즉, 당신이 있고 싶어한다는 뜻이죠.데이터베이스 연결 실패 시 자동으로 캡처이상을 얻는 것은 통하지 않는다. 왜냐하면 이것은 이상이 아니라 오류이기 때문입니다.하지만 자바에서는 예상과 다른 행동을 이상하다고 보고 포획하는 경우가 많다.
PHP 이상 처리는 닭고기옆구리?
위의 분석에서 우리는PHP는 적극적으로 이상을 던지지 않는다는 것을 알 수 있습니다.당신이 수동으로 이상을 던질 수 있다는 것은 어이가 없습니다. 만약 당신이 무엇이 잘못되었는지 알고 있다면, 당신이 ifelse를 추가하여 해결하면 되지 않습니까? 왜 수동으로 이상을 던질 수 있는지, 이왕 수동으로 던질 수 있다는 것은 이것이 이상이 아니라 예상된 것임을 증명합니다.내 이해로는 이것이 PHP가 계륵을 비정상적으로 처리하는 곳입니다(아니요).꼭 맞습니다). 그래서 PHP의 이상이메커니즘은 그렇게 완벽하지 않습니다. 하지만 프레임을 사용해 본 학생들은 이 상황을 알고 있습니다. 프레임에 php가 이상을 "자동"으로 캡처하는 코드를 직접 쓰는 것은 가능합니다. 왜죠?소스코드를 본 학생들은 프레임에 모두 세 가지 함수가 관련되어 있다는 것을 안다:register_shutdown_function,set_error_handler, set_exception_handler 뒤에는 세 가지 블랙 테크놀로지에 중점을 둘 것이며, 이 몇 가지 함수를 통해 PHP가 이상과 오류를 거짓으로 캡처할 수 있습니다.
둘, ERROR의 클래스
1 Fatal Error: 치명적인 오류 (스크립트 실행 중지)
2 E_ERROR//치명령된 실행 오류, 오류를 복구할 수 없음, 스크립트 실행 중지
3E_CORE_ERROR//PHP 부팅 시 초기화 중 치명적인 오류
4E_COMPILE_ERROR//편Zend 스크립트 엔진에 의해 E_ERROR이 생성된 것처럼 치명적인 오류를 번역합니다.
5E_USER_ERROR//자오류 메시지를 정의합니다. 예를 들어 PHP 함수 trigger_error (오류 유형은 E_USER_ERROR로 설정됨)
6
7 Parse Error: 컴파일 시 구문 오류 해결 오류(스크립트 실행 중지)
8 E_PARSE // 컴파일 시 구문 분석 오류잘못하다
9
10 Warning Error: 경고 오류 (알림만 제공)메시지, 스크립트 실행 중지 안 함)
11 E_WARNING// 런타임 경고 (비치명적 오류).
12 E_CORE_WARNING// PHP 초기화 시작 중 발생한 경고 (비치명적 오류)
13 E_COMPILE_WARNING// 컴파일된 경고
14E_USER_WARNING// 사용자 생성 경고 메시지
15
16 Notice Error: 알림 오류 (알림 메시지만 제공)이자, 스크립트 실행 중지 안 함)
17 E_NOTICE// 런타임알림. 스크립트가 오류로 나타날 수 있는 상황을 나타냅니다.
18 E_USER_NOTICE//사용자제생의 통지 메시지
ERROR 수준의 오류를 생성하는 5가지 범주가 있음을 알 수 있으며, 이 오류는 PHP 프로그램의 종료로 직접 이어집니다.
다음과 같이 정의할 수 있습니다
1 ERROR = E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_PARSE
3. PHP 이상 처리의 블랙 테크놀로지
앞에서 말씀드린 프레임은 포획이 가능한 곳이고일부 오류와 비정상적인 것이 실현될 수 있는 이유는 블랙 테크놀로지를 사용했기 때문입니다, 하하!사실 블랙테크도 아니고, 주로 세 가지 중요한 함수입니다.
1:set_error_h앤들러( )
이 이름을 보면 알 것 같다즉, 이 함수는 오류를 캡처하고 사용자 정의 오류 처리 함수를 설정하는 데 사용됩니다
1 <?php
2 set_error_handler('zyferror');
3 function zyferror($type, $message, $file, $line)
4 {
5 var_dump('<b>set_error_handler: ' . $type . ':' . $message . ' in ' . $file . ' on ' . $line . ' line .</b><br />');
6 }
7 ?>
프로그램에 오류가 발생하면 이 방법이 자동으로 호출되지만 두 가지 점에 유의해야 합니다. 첫째, 이 방법이 존재하면 해당 error_reporting()을 사용할 수 없습니다.모든 오류는 사용자 정의 함수에 의해 처리됩니다.둘째, 이 방법은 E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, set_error_handler( ) 기능이 있는 파일에서 생성된 E_STRICT로 시스템에서 생성된 Warning 및 Notice 수준의 오류만 캡처할 수 있습니다.
그리고 그는 여러 가지 방법을 가지고 있습니다
1 <?php
2 // 다이렉트 패스워드 이름 NonClassFunction
3 set_error_handler('function_name');
4
5 // 传 class_name && function_name
6 set_error_handler(array('class_name', 'function_name'));
7 ?>
2:register_shutdown_function()
PHP 캡처 오류: Fatal Error, Parse Error 등, 이 방법은 PHP 스크립트 실행이 종료되기 전에 마지막으로 호출되는 함수입니다. 예를 들어 스크립트 오류, die(), exit, 이상, 정상 종료가 모두 호출됩니다. 얼마나 터무니없는 함수입니까!이 함수를 통해 스크립트가 끝나기 전에 이 실행에서 오류가 발생했는지 여부를 판단할 수 있으며, 이때 함수인 error_get_last( )의 도움으로 이 실행에서 발생하는 모든 오류를 얻을 수 있습니다.error_get_last( ); 반환된 메시지:
[type] - 오류 유형
[메시지] - 오류 메시지
[file] - 오류가 발생한 장소파일
[line] - 오류가 발생한 행
1 <?php
2 register_shutdown_function('zyfshutdownfunc');
3 function zyfshutdownfunc()
4 {
5 if ($error = error_get_last()) {
6 var_dump('<b>register_shutdown_function: Type:' . $error['type'] . ' Msg: ' . $error['message'] . ' in ' . $error['file'] . ' on line ' . $error['line'] . '</b>');
7 }
8 }
9 ?>
이를 통해 프로그램이 종료되기 전의 모든 오류 정보를 교묘하게 출력할 수 있다.그러나 테스트를 할 때 모든 오류가 종료된 후에 이 함수를 호출하는 것은 아니라는 것을 알았습니다. 다음 테스트 파일을 볼 수 있습니다. 내용은 다음과 같습니다
1 <?php
2 register_shutdown_function('zyfshutdownfunc');
3 function zyfshutdownfunc()
4 {
5 if ($error = error_get_last()) {
6 var_dump('<b>register_shutdown_function: Type:' . $error['type'] . ' Msg: ' . $error['message'] . ' in ' . $error['file'] . ' on line ' . $error['line'] . '</b>');
7 }
8 }
9 var_dump(23+-+); //여기 문법 오류
10 ?>
직접 시도해 볼 수 있습니다. zyfshutdownfunc() 함수를 전혀 트리거하지 않는다는 것을 알 수 있습니다. 사실 이것은 문법 오류입니다. 바로 하나 보고합니다
1 <?php
2 Parse error: syntax error, unexpected ')' in /www/mytest/exception/try-catch.php on line 71
3 ?>
그래서 무엇이 촉발되지 않고 왜 틀 안에서 가능한가 하는 기이한 질문을 이끌어냈다.그 이유는 매우 간단합니다. parse-time 오류가 발생할 때만 이 함수를 호출하지 않습니다.이 함수는 run-time 에러시에만 호출됩니다. 구문 검사기 전에 register_shutdown_function()을 실행하여 등록해야 하는 함수를 호출 스택에 넣지 않았기 때문에 전혀 실행되지 않는 것으로 이해됩니다.그 틀에서는 왜 어떤 오류도 register_shutdown_function()에 들어갈 수 있습니까? 사실 틀에서는 일반적으로 동일한 엔트리 index.php가 있습니다. 그러면 각 라이브러리 파일은 include **를 통해 index.php에 로드됩니다. 상당히 모든 프로그램이 index.php에 모이게 됩니다. 마찬가지로, 당신이 쓴 문법 오류가 있는 파일도 엔트리 파일에 도입됩니다. 그러면 틀을 호출하여 index.php를 실행할 때 index.php 자체가 문법 오류가 없고 parse-time 오류가 발생하지 않습니다.
그래서 이제 이 쓰기를 시도해 보세요. 그러면 zyfshutdownfunc()가 콜백됩니다
1 a.php 파일
2 <?php
3 // 시뮬레이션 문법 오류
4 var_dump(23+-+);
5 ?>
6
7 b.php 파일
8 <?php
9 register_shutdown_function('zyfshutdownfunc');
10 function zyfshutdownfunc()
11 {
12 if ($error = error_get_last()) {
13 var_dump('<b>register_shutdown_function: Type:' . $error['type'] . ' Msg: ' . $error['message'] . ' in ' . $error['file'] . ' on line ' . $error['line'] . '</b>');
14 }
15 }
16 require 'a.php';
17 ?>
3:set_exception_handler()
사용하지 않는 try/cat에 사용할 기본 예외 핸들러 설정ch 블록은 이상을 포착하기 위해 사용되며, 즉 던져진 이상을 포착했는지 여부에 관계없이 아무도 포착하지 않으면 이 방법에 들어가고 콜백 함수가 호출된 후 이상이 중단됩니다.사용법을 살펴보다:
1 <?php
2 set_exception_handler('zyfexception');
3 function zyfexception($exception)
4 {
5 var_dump("<b>set_exception_handler: Exception: " . $exception->getMessage() . '</b>');
6 }
7 throw new Exception("zyf exception");
8 ?>
4.교묘하게 오류와 이상을 포착
1:오류를 비정상적인 형태로던지기 (완전히 던질 수 없음)
위의 설명으로 우리는 안다.도, php의 오류는 비정상적인 모습으로 포착할 수 없지만,우리는 그들이 try-catch의 확장 범위에 도달하도록 던져야 합니다. 우리는 앞에서 set_error_handler() 방법을 설명했습니다. 그가 무엇을 사용했는지, 그는 잘못 캡처했기 때문에, 우리는 그의 도움을 받아 잘못된 캡처한 다음 비정상적인 형태로 던질 수 있습니다. ok, 다음 쓰기를 시도합니다.
1:오류를 비정상적인 형태로던지기 (완전히 던질 수 없음)
위의 설명으로 우리는 안다.도, php의 오류는 비정상적인 모습으로 포착할 수 없지만,우리는 그들이 try-catch의 확장 범위에 도달하도록 던져야 합니다. 우리는 앞에서 set_error_handler() 방법을 설명했습니다. 그는 무엇을 사용합니까? 그는 잘못된 것을 캡처합니다. 그래서 우리는 그의 도움을 받아 잘못된 것을 캡처한 다음 비정상적인 형태로 던질 수 있습니다. ok, 다음 글쓰기를 시도해 봅니다: 1: 오류를 비정상적인 형태로 던질 수 없습니다(완전히 던질 수 없습니다).
위의 설명으로 우리는 안다.도, php의 오류는 비정상적인 모습으로 포착할 수 없지만,우리는 그들이 try-catch의 확장 범위에 도달하도록 던져야 합니다. 우리는 앞에서 set_error_handler() 방법을 설명했습니다. 그가 무엇을 사용했는지, 그는 잘못 캡처했기 때문에, 우리는 그의 도움을 받아 잘못된 캡처한 다음 비정상적인 형태로 던질 수 있습니다. ok, 다음 쓰기를 시도합니다
1 <?php
2 set_error_handler('zyferror');
3 function zyferror($type, $message, $file, $line)
4 {
5 throw new \Exception($message . 'zyf 오류 이상');
6 }
7
8 $num = 0;
9 try {
10 echo 1/$num;
11
12 } catch (Exception $e){
13 echo $e->getMessage();
14 }
15 ?>
1 Division by zero zyf123
프로세스: 원래 오류 0을 제거한 다음 set_error_handler()를 트리거하고 set_error_handler()에서 리턴 샷을 죽인 다음 오류 메시지를 비정상적인 형태로 던지면 오류가 비정상적인 형태로 던질 수 있습니다.이렇게 하는 데는 단점이 있으며 set_error_handler() 함수의 캡처 수준에 의해 제한된다는 점에 유의해야 합니다.
2: 모든 오류 캡처
set_error_handler( )에서 시스템 수준 E_ERROR, E_PARSE 및 기타 오류의 일부를 캡처할 수 있지만 이 부분은 register_shutdown_function( )에 의해 캡처될 수 있음을 알 수 있습니다.그래서 이 둘을 결합하면 좋은 기능이 나올 수 있습니다.
다음 프로그램을 보십시오
1 a.php 내용:
2 <?
3 // 몰드Fatalerror 오류
4 //test()
5
6 // 몰드ERROR 오류 발생 예정
7 //trigger_error('zyf-error'), E_USER_ERROR)
8
9// 몰드의어법 오류
10 var_dump(23+-+)
11
12 // 몰드Notice 작성 오류
13 //echo $f;
14
15 // 몰드Warning 오류
16 //echo '123';
17 //ob_flush()
18 //flush()
19 //header("Content-type:text/html;cha)rset=gb2312"),
20 ?>
21 b.php 내용:
22 <?
23 error_리포팅(0)
24 register_shutdown_function('zyfshutd)ownfunc')
25 function zyfshutdownfunc( )
26 {
27 if ($error = error_get_last()) {
28 var_dump('<b>register_shutdown_function: Type:' . $error['type'] . ' Msg: ' . $error['message'] . 'in'. $error['file'']. ' on line'. $error['line']. '</b>')
29 }
30 }
31
32 set_error_handler('zyferror');
33 function zyferror($type, $message, $)file, $line)
34 {
35 var_dump('<b>set_error_handler: ' . $type. ':' $message. 'in'. $file. ' on'. $line. 'line. </b> <br />');
36 }
37
38 require 'a.php';
39 ?>
여기서 시작하는 프로그램을 설명할 수 있겠죠. test.php는 단일 파일 실행으로는 오류를 캡처할 수 없습니다. 프레임에서 실행하면 됩니다. 물론 위에서 설명한 대로 확장해도 됩니다.
1: 사용자 정의 예외 처리
복잡한 시스템에서 우리는 종종 특별한 상황에서 배출될 수 있는 특별한 처리가 필요한 이상을 스스로 포착해야 합니다.그래서 우리는 스스로 이상 포획 클래스를 정의하는데, 이 클래스는 반드시 exception이어야 한다. 클래스의 확장, 클래스가 상속됨 PHP의 exception 클래스의 모든 속성, 그리고 우리는 사용자 정의 함수를 추가할 수 있습니다. 사용할 때는 사실 이전과 같으며 대략적으로 다음과 같이 씁니다
1 <?php
2 class zyfException extends Exception
3 {
4 public function errorzyfMessage()
5 {
6 return 'Error line ' . $this->getLine().' in ' . $this->getFile()
7 .': <b>' . $this->getMessage() . '</b> Must in (0 - 60)';
8 }
9 }
10
11 $age = 10;
12 try {
13 $age = intval($age);
14 if($age > 60) {
15 throw new zyfException($age);
16 }
17
18 } catch (zyfException $e) {
19 echo $e->errorzyfMessage();
20
21 }
22 ?>
2 : 이상 네스트
이상 네스트비더 일반적인 쓰기 방법, 사용자 정의 예외 처리에서 try 블록은 여러 예외 캡처를 정의한 다음 이상을 계층적으로 전달할 수 있으며 이해는 버블링과 유사합니다
1 <?php
2 $age = 10;
3 try {
4 $age = intval($age);
5 if($age > 60) {
6 throw new zyfException($age);
7 }
8
9 if ($age <= 0) {
10 throw new Exception($age . ' must > 0');
11 }
12
13 } catch (zyfException $e) {
14 echo $e->errorzyfMessage();
15
16 } catch(Exception $e) {
17 echo $e->getMessage();
18 }
19 ?>
물론 캐치에서 다시 상층부에 이상을 던질 수도 있다:
1 <?php
2 $age = 100;
3 try {
4 try {
5 $age = intval($age);
6 if($age > 60) {
7 throw new Exception($age);
8 }
9
10 } catch (Exception $e) {
11 throw new zyfException($age);
12
13 }
14
15 } catch (zyfException $e) {
16 echo $e->errorzyfMessage();
17 }
18 ?>
6. PHP7에서의 이상 처리
지금 PHP를 쓰려면 버전을 고려해야 돼요이 경우 위의 쓰기는 PHP7에서 대부분 구현될 수 있지만 다른 점도 있습니다. PHP7 업데이트에서는 더 많은 Error가 캡처 가능한 Exception으로 바뀌었습니다. 현재의 PHP7은 글로벌 throwable 인터페이스를 구현했습니다. 원래 오래된 Exception과 그 중 일부 Error가 이 인터페이스를 구현했습니다(interface), PHP7에서 더 많은 Error가 캡처 가능한 Exception으로 반환되었습니다. 이렇게 하면 사실 앞에서 언급한 확장된 try-catch의 영향 범위와 같습니다
1 <?php
2 try {
3 test();
4
5 } catch(Throwable $e) {
6 echo $e->getMessage() . ' zyf';
7 }
8
9 try {
10 test();
11
12 } catch(Error $e) {
13 echo $e->getMessage() . ' zyf';
14 }
15 ?>
PHP7은 throwable 인터페이스를 구현하기 때문에 첫 번째 방식을 사용하여 이상을 포착할 수 있습니다.또한 일부 Error가 인터페이스를 구현하고 더 많은 Error가 캡처 가능한 Exception으로 변경되기 때문에 두 번째 방법을 사용하여 이상을 캡처할 수 있습니다.다음은 인터넷에서 찾은 PHP7의 이상 계층 트리입니다.
Throwable
Exception 이상
...
Error 오류
ArithmeticError 연산 오류
DivisionByZeroError 나눗셈이 0인 오류
AssertionError 선언 오류
ParseError 오류 해결
TypeError 형식 오류
'개발 꿀팁 > PHP' 카테고리의 다른 글
php는 openssl을 사용하여 aes를 암호화하고 복호화한다 (0) | 2022.09.26 |
---|---|
php 구현 데몬 (0) | 2022.09.26 |
php 해석 yaml (0) | 2022.09.23 |
php 신호 처리 (0) | 2022.09.23 |
PHP에서 웹 페이지 건너뛰기 방법 (0) | 2022.09.23 |