오늘은 PHP에서 스크립트 실행 중 발생하는 오류 일부를 잡아내서 처리한 뒤 다음 코드를 계속 실행하게 만들어주는 메소드에 대해 알아보고 예제를 만들어 보겠습니다.
사용자 정의 오류 처리기는 다음과 같이 등록할 수 있습니다.
set_error_handler(?callable $callback, int $error_levels = E_ALL): string|array|object|null
$callback : 콜백 메소드는 해당 에러를 잡았을 때 실행할 메소드를 설정
$error_levels = E_ALL : 에러 레벨 같은 경우 해당 오류 처리기가 처리할 오류의 종류를 설정, 이때 $error_levels 같은 경우 매개변수로 값을 주지 않았을 때 기본값인 E_ALL로 설정됩니다.
또한 사용자 정의 오류 처리기는 E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING 에러를 처리할 수 없고 E_STRICT의 경우 set_error_handler() 메소드가 호출된 파일에서 발생한 경우만 처리할 수 있습니다.
콜백 메소드(첫번째 매개변수)는 다음과 같이 정의할 수 있습니다.
handler(
int $errno,
string $errstr,
string $errfile = ?,
int $errline = ?,
array $errcontext = ?
): bool
EXAMPLE
function myErrorHandler($errno, $errstr, $errfile, $errline){
// code to execute
}
$errno: 발생한 오류 수준을 정수로 전달
$errstr: 오류 메시지를 문자열로 전달
$errfile: 오류가 발생한 파일 이름이 문자열로 전달(필수 매개변수 X)
$errline: 오류가 발생한 행 번호가 정수로 전달(필수 매개변수 X)
$errcontext: 오류가 발생한 지점의 활성 기호 테이블을 가리키는 배열이 전달, 즉 errcontext는 오류가 발생한 범위에 존재하는 모든 변수의 배열을 포함한다(PHP 7.2 버전부터 deprecated 되었고 PHP 8.0 버전부터 제거되었습니다)
위 메소드에서 true를 반환하면 해당 오류를 적절히 처리했으니 추가 처리가 필요하지 않음을 의미하고 반대로 false를 반환하거나 아무것도 반환하지 않는다면 false를 반환한 것으로 간주해 추가적인 오류 처리를 지시할 수 있습니다.
에러 레벨(두번째 매개변수)에는 다음과 같이 총 16가지가 있습니다.
Error Level Value Description
E_ERROR | 1 | 복구할 수 없는 치명적인 런타임 오류로, 스크립트 실행이 즉시 중지됩니다. |
E_WARNING | 2 | 런타임 경고로, 비 치명적이며 대부분의 오류가 이 범주에 속합니다. 스크립트 실행은 중지되지 않습니다. |
E_PARSE | 4 | 컴파일 시간에 발생하는 구문 분석 오류로, 파서에 의해서만 생성됩니다. |
E_NOTICE | 8 | 런타임 알림으로, 스크립트가 정상적으로 실행될 때 발생할 수 있는 오류 상황을 나타냅니다. |
E_CORE_ERROR | 16 | PHP 엔진 초기 시작 중에 발생하는 치명적인 오류입니다. 이는 E_ERROR와 유사하지만 PHP의 코어에서 생성됩니다. |
E_CORE_WARNING | 32 | PHP 엔진 초기 시작 중에 발생하는 비 치명적인 오류입니다. 이는 E_WARNING과 유사하지만 PHP의 코어에서 생성됩니다. |
E_COMPILE_ERROR | 64 | 스크립트 컴파일 중에 발생하는 치명적인 오류입니다. 이는 E_ERROR와 유사하지만 Zend 스크립팅 엔진에서 생성됩니다. |
E_COMPILE_WARNING | 128 | 스크립트 컴파일 중에 발생하는 비 치명적인 오류입니다. 이는 E_WARNING과 유사하지만 Zend 스크립팅 엔진에서 생성됩니다. |
E_USER_ERROR | 256 | 사용자가 생성한 치명적인 오류 메시지로, trigger_error() 함수를 사용하여 PHP 코드에서 생성됩니다. |
E_USER_WARNING | 512 | 사용자가 생성한 비 치명적인 경고 메시지로, trigger_error() 함수를 사용하여 PHP 코드에서 생성됩니다. |
E_USER_NOTICE | 1024 | 사용자가 생성한 알림 메시지로, trigger_error() 함수를 사용하여 PHP 코드에서 생성됩니다. |
E_STRICT | 2048 | 엄격한 의미에서의 오류는 아니지만 PHP가 문제나 미래 호환성으로 이어질 수 있는 코드를 만났을 때 발생합니다. |
E_RECOVERABLE_ERROR | 4096 | 잡을 수 있는 치명적인 오류로, 오류는 치명적이었지만 PHP 엔진을 불안정한 상태로 만들지 않았습니다. 사용자 정의 오류 처리기에 의해 잡히지 않으면 (set_error_handler() 참조), 응용 프로그램은 E_ERROR처럼 중단됩니다. |
E_DEPRECATED | 8192 | 미래의 PHP 버전에서 코드가 작동하지 않을 것임을 나타내는 런타임 알림입니다. |
E_USER_DEPRECATED | 16384 | 사용자가 생성한 경고 메시지로, trigger_error() 함수를 사용하여 PHP 코드에서 생성됩니다. |
E_ALL | 32767 | 모든 에러와 경고를 나타냅니다, 5.4.0 버전에서는 E_STRICT 레빌을 제외합니다. |
위 내용을 바탕으로 예제를 하나 만들어 보겠습니다.
// 사용자 정의 에러핸들러
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
// 사용자가 만든 에러핸들러에서 처리할 수 있는지 확인
if (!(error_reporting() & $errno)) {
// error_reporting() 메소드는 에러가 있다면 에러레벨의 수준에 해당하는 값을 반환하고 없다면 0을 반환
// $errno은 에러레벨의 수준을 반환하는데 에러가 없다면 0을 가짐
// 둘 중 하나 또는 둘 다 0을 반환한다면 false를 반환해 추가적인 에러처리가 필요함을 알림
return false;
}
// $errstr에 있는 HTML 코드가 실행되지 않게 문자열로 그자체로 사용할 수 있게 변환
$errstr = htmlspecialchars($errstr);
switch ($errno) { // 입력된 $errno에 따라서 코드를 실행
case E_USER_ERROR:
echo "<b>My ERROR</b> [$errno] $errstr<br />\\n";
echo " Fatal error on line $errline in file $errfile";
echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />\\n";
echo "Aborting...<br />\\n";
exit(1);
case E_USER_WARNING:
echo "<b>My WARNING</b> [$errno] $errstr<br />\\n";
break;
case E_USER_NOTICE:
echo "<b>My NOTICE</b> [$errno] $errstr<br />\\n";
break;
default:
echo "Unknown error type: [$errno] $errstr<br />\\n";
break;
}
// 에러를 처리한 뒤 true를 반환해 추가적인 에러처리가 필요없음을 알림
return true;
}
// 사용자 정의 에러핸들러를 테스트하기 위한 메소드
function scale_by_log($vect, $scale)
{
if (!is_numeric($scale) || $scale <= 0) {
// trigger_error() 메소드를 사용해 에러 발생
trigger_error("log(x) for x <= 0 is undefined, you used: scale = $scale", E_USER_ERROR);
}
if (!is_array($vect)) {
// trigger_error() 메소드를 사용해 에러 발생
trigger_error("Incorrect input vector, array of values expected", E_USER_WARNING);
return null;
}
$temp = array();
foreach($vect as $pos => $value) {
if (!is_numeric($value)) {
// trigger_error() 메소드를 사용해 에러 발생
trigger_error("Value at position $pos is not a number, using 0 (zero)", E_USER_NOTICE);
$value = 0;
}
$temp[$pos] = log($scale) * $value;
}
return $temp;
}
// 사용자 정의 에러핸들러 설정 및 참조
$old_error_handler = set_error_handler("myErrorHandler");
// 에러를 발생시키기 위해 숫자가 아닌 아이템을 갖고 있는 첫번째 배열을 만듬
echo "vector a\\n";
$a = array(2, 3, "foo", 5.5, 43.3, 21.11);
print_r($a);
// 두번째 배열 생성하며 scale_by_log() 메소드 사용
echo "----\\nvector b - a notice (b = log(PI) * a)\\n";
$b = scale_by_log($a, M_PI);
print_r($b);
// 에러를 발생시키기 위해 scale_by_log() 메소드 첫번째 매개변수에 의도적으로 배열이 아닌 string을 입력
echo "----\\nvector c - a warning\\n";
$c = scale_by_log("not array", 2.3);
var_dump($c); // NULL
// 치명적인 에러를 발생시키기 위해 scale_by_log() 메소드 두번째 매개변수에 음수를 입력
echo "----\\nvector d - fatal error\\n";
$d = scale_by_log($a, -2.5);
var_dump($d); // 치명적 에러 발생 후 exit(1) 메소드가 실행되어 절대로 실행될 수 없는 코드
이렇게 set_error_handler() 메소드를 사용해 사용자가 원하는 대로 PHP에서 발생하는 에러들을 처리하는 방법을 알아보았습니다.
다음에는 에러가 아니라 예외를 처리하는 set_exception_handler() 사용법을 알아보겠습니다.
'PHP' 카테고리의 다른 글
[PHP] ERROR 대비 종료 시 실행할 메소드 설정하기 (0) | 2023.11.19 |
---|---|
[PHP] 사용자 정의 예외 처리기[set_exception_handler()] 정의하기 (0) | 2023.11.10 |
[PHP] Retrofit 라이브러리를 사용해서 서버에 파일 업로드하기(서버) (0) | 2023.10.20 |
[PHP] 커스텀 토스트 메시지 띄우기 (0) | 2023.07.06 |
[PHP] 다양한 확장자의 파일을 업로드 해주는 함수 (0) | 2023.03.13 |