분류 php

모범 사례 : PHP에서 오류 및 예외 처리

컨텐츠 정보

  • 조회 379 (작성일 )

본문

소개 


저녁에는 강한 바람이 식고


날씨가 최근에 친절하지 않았으며 비가 지난 2 주 동안 계속 떨어졌으며 곧 멈추기를 원하지 않는 것 같습니다.


원본 : https://dev.to/anastasionico/good-practices-handling-error-and-exceptions-in-php-5d8c


공장 내부에서, 몇몇 사람들은 세상을 알고 있는 세상을 바꿀 수 있는 잠재력을 지닌 무언가에 대해 지옥처럼 일하고 있습니다.


Edison_-_his_life_and_inventions_%281910%29_%2814778250434%29.jpg 


최종 테스트는 몇 분 안에 이루어지며 몇 주 간의 연구, 노력 및 계산의 결과가 될 것입니다.


3


2


1


POP!


손전등이 잠시 동안 방을 밝았다가 다시 어두워졌고, 하루 더 지났고, 또 하나는 실패했습니다.


이것이 9,999 번째입니다.


“실패하지 않았습니다. 작동하지 않는 10,000 가지 방법을 찾았습니다.” 

토마스 에디슨


Brian Tracy, Tony Robin, Zig Ziglar 또는 Jim Rohn과 같은 동기 부여 연사를 들어 본 적이 있다면, 전 세계의 학교 운영 방식에 문제가 있음을 알고 있습니다.


대학에서 오류는 환영받지 않고 처벌됩니다.


하지만 현실에서는 오류가 더 나은 방법이 될 수 있는 유일한 방법입니다.


이것은 웹 개발에서 특히 그렇습니다.


시련과 실수는 확실히 위대해지고 기술을 연마하는 가장 좋은 방법입니다.


우리가 실수를 저지르고 조심해야 한다는 것도 사실입니다.


실수를 저지른 이유는 오류를 관리하고 배울 수 있기 때문입니다.


PHP를 사용하면 코드에서 발생할 수 있는 오류를 쉽게 처리, 관리 및 학습 할 수 있습니다.


PHP 7에서 오류를 관리하는 방법 


PHP 5.6과 PHP 7 또는 PHP 7.1 사이에서 가장 많이 개선 된 기능이 무엇인지 묻는다면 반드시 오류 처리를 상위 3 위에 놓을 것입니다.


사랑하는 프로그래밍 언어의 일곱 번째 버전은 정의 된 목표를 가진 인터페이스를 제공했습니다.


쉽게 구현하고 많은 경우에 유용해야 했습니다.


던질 수 있는 인터페이스


실제로, 클래스 유형 (오류 클래스 및 예외)과 공급 및 오류를 더 잘 이해하고 분석하는 데 사용할 수 있는 소수의 메소드로 구현할 수 있습니다.


여기 클래스와 사용법을 볼 수 있습니다.


Throwable {
    abstract public getMessage ( void ) : string
    abstract public getCode ( void ) : int
    abstract public getFile ( void ) : string
    abstract public getLine ( void ) : int
    abstract public getTrace ( void ) : array
    abstract public getTraceAsString ( void ) : string
    abstract public getPrevious ( void ) : Throwable
    abstract public __toString ( void ) : string
}
Try {
    // some code
} catch (Throwable $e) {
    echo "an instance of class Throwable has been caught";
}


위의 스니펫에는 스크립트에서 PHP 오류를 디버깅 하는 데 사용할 수 있는 모든 방법이 나와 있습니다 (많은 유형 힌트 포함)



실제 코드를 사용하여 코드 블록을 시도하고 오류 또는 예외를 발생 시킬 수 있습니다.


어디서나 오류, 오류! 


PHP 5.6 이전의 오류를 처리 한 사람은 디버깅 단계에서 어떤 유형의 고통과 두통을 처리해야 하는지 알고 있습니다.


이전에는 엔진 내에서 오류가 발생했으며 치명적인 오류가 아닌 한 오류를 처리 할 수 있었습니다.


또한 오류와 예외가 코드에서 완전히 다른 두 가지라는 점을 고려해야 하고 이미 복잡한 상황에 또 다른 난이도가 추가되었습니다.


PHP7부터는 치명적 오류로 인해 오류 예외가 발생하고 맞춤형 메소드를 사용하여 치명적이지 않은 오류를 쉽게 관리 할 수 ​​있습니다.


예를 들어 일부 코드를 실행할 수 있으며 치명적인 경우에만 오류가 발생할 수 있습니다.


try {
    echo $thisVariableIsNotSet;
    inexistentFunctionInvoked();
} catch (Error $e) {
    echo "Error: $e->getMessage()";
}
// Error: Call to undefined function inexistentFunctionInvoked();


이것이 처음 오류를 처리하거나 try-catch를 보는 경우 혼란스러워 보일 수 있습니다. 조금 뒤로 물러서고 싶을 수도 있습니다.


걱정하지 마십시오. Php Basics에서는 이 기사를 읽을 준비가 되기 위해 알아야 할 모든 것을 찾을 수 있습니다.


무슨 일이 일어나고 있는지 설명하면서 나와 함께 견뎌내십시오.


우리의 의사 코드에서 우리는 변수와 함수를 요소로 지정해야 합니다. 둘 다 정의되지 않았으므로, 존재하지 않거나 존재하지 않습니다.


PHP는 정의되지 않은 함수와 다르게 설정되지 않은 변수를 처리합니다.


첫 번째 변수는 유효하지 않은 변수이며 통지 오류입니다.


두 번째 오류는 실제로 중요한 기능을 가진 실제 기능입니다.


PHP에서 정의되지 않은 함수가 심각한 문제, 치명적인 오류인 이유입니다.


try 블록 내에 이 두 줄의 코드를 사용하면 catch에서 Error 클래스의 인스턴스 (변수 $e)를 표시 할 수 있습니다.


$e는 Throwable 인터페이스를 구현합니다. 즉, 이전 단락에서 본 모든 방법을 사용할 수 있습니다. 따라서 $e-> getMessage();


맞춤형 오류 처리기 만들기 


Error 클래스에 영향을 미치지 않는 일부 오류가 발생할 수 있습니다.


이러한 오류가 치명적이지 않은 경우, PHP를 사용하면 개발자가 맞춤형 기능을 정의하고 원하는 방식으로 처리 할 수 ​​있습니다.


그렇게 하려면 set_error_handle() 함수를 사용해야 합니다.


이 함수는 사용하려는 함수의 이름을 가진 문자열 또는 호출하는 메소드의 이름과 객체를 포함하는 배열을 허용합니다.


함수는 스크립트를 중지 시킬 수 있습니다.


값을 계속하거나 반환하지 않으려면 코드가 처음에 함수를 호출했을 때 계속하십시오.


실용적이면서도 쉬운 예를 아래에서 살펴 보겠습니다.


set_error_handle ()은 치명적 오류를 관리 할 수 ​​없습니다. 즉, 오류를 테스트하려면 경고를 시뮬레이트해야합니다 (0으로 나누기).


그런 다음 함수의 내용을 정의하고 오류가 발생할 때 오류를 포착합니다.


function myErrorHandler($errno, $errstr, $errfile, $errline) {
    echo "An error occurred in line {$errline} of file {$errfile} with message {$errstr}";
}

set_error_handler("myErrorHandler");

try {
    5 / 0;
} catch (Throwable $e) {
    echo $e->getMessage();
}

// An error occurred in line 1 of file /index with message Division by zero


오류가 발생하면 프로덕션 환경에서 오류를 숨기고 로컬 또는 스테이징 서버에서만 볼 수 있음을 잊지 마십시오.


실제로 프로덕션 오류를 표시하면 해커 나 악의적 인 사용자에게 웹 사이트의 취약성에 대한 방대한 힌트를 줄 수 있습니다.


이를 위해 php.ini에서 3 가지 설정을 편집 할 수 있습니다

  • display_errors false로 설정되면 오류를 억제합니다.
  • log_errors는 오류를 로그 파일에 저장합니다.
  • error_reporting은 보고서를 트리거 하는 오류 유형을 구성합니다.

오류 처리 함수 


PHP에는 이 섹션에서 오류를 처리하고 쉬운 작업을 수행 할 수 있는 몇 가지 기능이 있으며 각 기능에 대한 간단한 설명을 제공합니다.

  • debug_ • backtrace() 옵션의 플래그와 같은 몇 가지 매개 변수와 결과를 제한하는 숫자를 받아들이고 스크립트가 있는 위치에 대한 요약을 생성하며 배열 변수를 반환합니다.
  • debug_ • print_ • backtrace() 이전 트레이스와 비슷한 방식으로 작동하지만 트레이스 배열을 만드는 대신 역순으로 인쇄합니다.
  • error_ • get_ • last() 스크립트에서 마지막으로 발생한 오류 정보가 포함 된 연관 배열을 반환합니다.
  • error_ • clear_ • last()는 PHP의 내부 오류 로그를 재설정 합니다. error_get_last() 전에 사용되면 후자는 null을 반환합니다.
  • error_ • log ()매개 변수로 필수 메시지가 필요하며 정의 된 오류 처리 루틴으로 전송합니다.
  • error_ • reporting()이 함수는 매개 변수로 none 또는 error 상수를 필요로 하고 (https://www.php.net/manual/en/errorfunc.constants.php에서 전체 목록을 찾을 수 있음) 정확도 수준을 설정하십시오. 오류를 처리 할 때 PHP 응용 프로그램에 있어야 합니다.
  • set_ • error_ • handler() 및 set_ • exception_ • handler()는 오류 및 예외를 처리하는 맞춤형 함수를 설정합니다.
  • restore_ • error_ • handler() 및 restore_ • exception_ • handler() set_ • error_ • handler() 및 set_ • exception_ • handler() 뒤에 사용됩니다. 이전 오류 처리기로 되 돌리는 것이 목표입니다. -또는 사용자 정의 함수;
  • trigger_ • error()이 함수는 메시지를 필수 매개 변수로, error_type의 플래그를 임의의 것으로 수락하여 오류를 트리거 합니다.
  • user_ • error() 트리거 별명 _error();

PHP 매뉴얼은 위 함수 중 일부에서 플래그로 사용할 수 있는 사전 정의 된 상수의 전체 목록을 제공합니다.


예외란 무엇인가 


예외는 PHP의 비교적 새로운 기능이며, PHP5에서만 구현되었지만 빠르게 객체 지향 프로그래밍 스크립트의 핵심 부분이 되었습니다.


예외는 스크립트가 정상적으로 실행되고 있지 않기 때문에 특별한 처리가 필요한 스크립트의 상태입니다.


오류와 예외는 모두 Throwable 인터페이스를 구현하는 클래스입니다.


OOP 세계의 다른 클래스와 마찬가지로


오류 계층을 작성하고 예외 처리 방식을 사용자 정의 할 수 있습니다.


주의를 기울이고 오류와 오해를 일으킬 수 있는 것은 자신의 클래스를 선언 할 수 없고 예외를 던지기로 결정한다는 것입니다.


에러를 던질 수 있는 유일한 클래스는 Throwable 클래스를 구현하는 클래스입니다.


게임을 하고 코드를 보고 다음 질문에 답합시다.


class MainException extends Exception {}
class SubException extends MainException {}

try {
    throw new SubException("SubException thrown");
} catch (MainException $e) {
    echo "MainException thrown" . $e->getMessage();
} catch (SubException $e) {
    echo "SubException thrown" . $e->getMessage();
} catch (Exception $e) {
    echo "Exception thrown" . $e->getMessage();
}


어떤 예외가 발생합니까?


아래 예에서 throw 된 예외는 SubException이며, 예외를 확장하는 MainException에서 상속됩니다.


블록은 첫 번째 (위의 블록)에서 마지막 블록까지 평가되며 예외가 발생하면 예외가 클래스 이름과 일치 할 때 트리거 됩니다.


우리가 보여주고 싶은 메시지의 범위를 좁히고 결국에는 위의 모범 사례로 간주 될 수 있다


일치하는 클래스가 없는 경우 전체 검사에 PHP 클래스 예외를 사용합니다.


여러 예외를 한 번에 잡기 


지금까지 우리는 몇 번의 어획을 시도했습니다.


각 코드 블록은 서로 다른 오류가 있는 메시지를 에코합니다.


우리가 수십 가지의 다른 예외를 만드는 경우를 생각해보십시오.


12 개의 캐치 블록을 추가해야 합니까? 같은 방식으로 여러 유형의 오류를 처리하려면 어떻게 해야 합니까?


이 상황을 관리하기 위해 PHP는 파이프 키워드“| ";


사용 방법의 예는 다음과 같습니다.


class MainException extends Exception {}
class SubException extends Exception {}

try {
    throw new SubException;
} catch (MainException |  SubException $e) {
    echo "Exception thrown: " . get_class($e);
}
// Exception thrown: SubException


finally 키워드 


과거에 스위치 케이스 조건부 구조를 이미 보았을 것입니다.


그렇지 않은 경우 PHP의 조건문에 대한 전체 기사를 얻었습니다.


switch 문의 요소 중 하나는 평가 된 사례가 없으면 "default"블록 (있는 경우)이 실행되는 것입니다.


캐치 시도는 마지막으로 키워드를 제공하여 코드와 유사한 작업을 수행 할 수 있게 합니다.


try {
    $handle = fopen("c:\\folder\\resource.txt", "r");   
    // do some stuff with the file

    throw new Exception("Exception thrown");
} catch (Exception $e) {
    echo "Exception thrown" . $e->getMessage();
} finally {
    fclose ( resource $handle );
}


이 키워드는 일반적으로 try 블록 내에서 이전에 연 파일을 닫아야 할 때 위의 예와 같이 사용됩니다.


스크립트에서 예외가 일찍 발생하더라도 finally 블록 내부의 코드는 항상 실행됩니다.


그러나 이것이 귀하의 사건에 도움이 된다고 생각 될 때마다 자유롭게 사용할 수 있습니다.


이 기사가 유용하다고 생각하고 PHP의 모범 사례에 대해 자세히 알고 싶다면 아래 이미지를 클릭하십시오.


결론 


토마스 에디슨 (Thomas Edison)은 겸손한 출신이며 역사적 데이터를 통해 그가 가장 훌륭한 사람이 아니라는 것을 확인했습니다.


어쨌든, 창의적이고 열정적 인 사람들에 의해 자신을 둘러 쌀 수 있는 능력과 그의 잘못을 깊이 분석하고 배울 수 있는 능력으로 인해 그는 지금까지 살았던 최고의 발명가 중 한 사람, 틀림없이 그의 시대에서 가장 부유하고 유명한 사람 중 한 사람이 되었습니다.


망설임 없이 웹 개발자로서도 똑같이 할 수 있다고 말할 수 있습니다.


어쩌면 우리는 세계적으로 유명한 응용 프로그램을 발명하거나 웹 사이트를 사용하여 수십억 명의 사람들의 삶을 변화 시키지 않을 것입니다.


오류 관리는 이것의 기본 부분입니다.


올바르게 수행하는 방법을 배우고 PHP에서 사용 가능한 모든 가능성을 익히고 PHPUnit 및 Sentry와 같은 구성 요소를 사용하면 우리 각자가 이 작업을 쉽게 수행 할 수 있습니다.


현재 오류를 관리하는 데 사용할 수 있는 유용한 구성 요소 또는 웹 사이트 :

filp/whoops

nette/tracy

vimeo/psalm

sebastianbergmann/phpunit

codeception/codeception

getsentry/sentry

https://phpcodechecker.com

https://www.piliapp.com/php-syntax-check