전체 페이지뷰

2008년 10월 7일 화요일

[펌]PHP 오류핸들링

PHP에 있어서의 기본적인 오류 처리(Error Handling)는 매우 심플합니다.
에러 메시지와 함께 파일 이름, 줄번호(line number)가 나오고
에러를 설명하는 메시지가 브라우저로 보내집니다.




PHP 오류 처리(Error Handling)

스크립트나 웹애플리케이션을 만들때,
오류 처리는 매우 중요한 부분입니다.

만일 오류를 확인하는 코드가 허술하다면,
우선은 웹애플리케이션이 매우 전문적이지 않은 사람이 만든
인상을 주기 때문에 신뢰를 잃게 될것이고,
무엇보다 여러 보안 문제에 노출되게 됩니다.

이번 포스팅에서는 PHP에서 가장 흔히 쓰이는 오류 확인 방법에
대해서 보여드릴려고 합니다.

크게 다음과 같은 서로 다른 오류 처리방법에 대해 포스팅해 보겠습니다:

  • 간단한"die()"구문
  • 커스텀 에러(Custom error, =사용자 정의 오류)와 에러 트리거(Error trigger, =오류 발생 시키기)
  • 오류 보고하기


기본 오류 처리: die() 함수 사용하기

첫번째 예제는 텍스트 파일을 여는 간단한 스크립트 입니다.


<?php
$file=fopen("welcome.txt","r");
?>


만약에 파일이 존재하지 않는다면, 아래와 같은 오류가 뜹니다:

Warning: fopen(welcome.txt) [function.fopen]: failed to open stream: 
No such file or directory in C:\webfolder\test.php on line 2


사용자에게 위와 같은 형태의 오류 메시지가 뜨는걸 방지하려면,

파일에 접근하기 전에 존재하는지 미리 체크하면 되겠지요:

<?php
if(!file_exists("welcome.txt"))
{
die("File not found");
}
else
{
$file=fopen("welcome.txt","r");
}
?>


이제 파일이 존재하지 않는다면 다음과 같은 메시지가 화면에 뜹니다:

File not found

위의 코드는 맨 처음의 코드보다 더 효과적입니다.

처음에는 아예 오류를 처리하는 부분이 없었지만 위의 코드는

간단한 오류 처리 방식을 통해 에러가 발생했을때 스크립트의 실행을

멈출 수 있기 때문입니다.


하지만, 그냥 단순히 스크립트를 멈추는것이 항상 옳은 방법인것은

아닙니다. 이번에는 오류를 처리하는 PHP의 다른 함수와 방법을

보도록 합시다.




커스텀 에러 핸들러(Custom Error Handler, =사용자 정의 오류 처리기)

커스텀 에러 핸들러(사용자 정의 오류 처리기)를 만드는 것은 상당히 쉽습니다.

오류가 발생했을때 호출될 수 있는 자신만의 특별한 함수를 만들면 됩니다.


이 사용자 자신이 만든 함수는 최소한 두개의 매개변수(에러 레벨과 에러 메시지)를 처리 할 수 있어야 하지만 다섯개까지 매개변수를 지정할 수 있습니다.

(부가적으로 추가할 수 있는 매개변수: 파일, 줄번호, 오류 컨텍스트)


문법


오류_처리할_함수_이름(error_level,error_message,
error_file,error_line,error_context)

매개변수
설명
error_level 필수. 사용자 정의 에러를 위한 에러 리포트의 레벨을
상술합니다. 번호값 이어야만 합니다. 아래쪽이 표에 가능한 에러 리포트 레벨들이 있습니다.
error_message 필수. 사용자 정의 에러를 위한 오류 메시지를 상술합니다.
error_file 선택적. 에러가 발생한 파일 이름을 상술합니다.
error_line 선택적. 에러가 발생한 줄번호(line number)를 상술합니다.
error_context 선택적. 에러가 발생했을때 모든 변수와 그 변수의 값을 담은 배열을 상술합니다.


에러 리포트 레벨 (= 오류 보고 수준)

이 에러 리포트 레벨(오류 보고 수준)들은 사용자 정의 에러 핸들러를 위해 사용될 수 있는 서로 다른 유형의 에러 입니다:


상수
설명
2 E_WARNING 치명적이지 않은 런타임 에러입니다.
스크립트의 실행은 중지되지 않습니다.
8 E_NOTICE 스크립트가 오류일 수 있는것을 발견했지만, 정상적으로 스크립트를 실행할때도 발생할 수 있는것을 찾아냈을때 뜨는 런타임 통지 입니다.
256 E_USER_ERROR 사용자가 만들어낸 치명적인 에러 입니다. trigger_error() 함수를 이용해서 설정한 E_ERROR와 유사합니다.
512 E_USER_WARNING 사용자가 생성한 치명적이지 않은 경고 입니다. trigger_error() 함수를 이용해서 설정한 E_WARNING과 유사합니다.
1024 E_USER_NOTICE 사용자가 생성한 통지 입니다. trigger_error() 함수를 이용해서 설정한 E_NOTICE와 유사합니다.
4096 E_RECOVERABLE_ERROR 잡아낼 수 있는 치명적 에러. E_ERROR과 유사하지만, 사용자 정의 핸들을 통해 잡아낼 수 있습니다. (set_error_handler()을 한번 보세요.)
8191 E_ALL E_STRICT 레벨을 제외한 모든 에러와 경고 입니다. (E_STRICT는 PHP 6.0에서 E_ALL의 한 부분이 될 예정입니다.)


이제 오류를 처리할 수 있는 함수를 만들어 봅시다:

function customError($errno, $errstr)
{
echo "<b>Error:</b> [$errno] $errstr<br />";
echo "Ending Script";
die();
}

위의 코드는 간단한 에러 핸들링(오류 처리) 함수 입니다.

이 함수가 실행되면, 에러 레벨(오류 수준)과 에러 메시지를 받아오게 됩니다.


그리고 나서는 에러 레벨과 메시지를 출력하고 스크립트를 중지 시킵니다.


이제 오류를 처리하는 함수를 만들었고

언제 실행되어야 할지 결정해야할 차례군요.


 



에러 핸들러(오류 처리기) 설정하기

PHP를 위한 기본 에러 핸들러(오류 처리기)는 내장 오류 처리기 입니다.

스크립트가 실행되는 동안 위의 함수가 기본 에러 핸들러(오류 처리기)가 되도록 만들어 봅시다.


몇 가지 에러에만 적용되도록 에러 핸들러(오류 처리기)를 변경하는게 가능하고, 그러한 방법으로 스크립트가 서로 다른 에러를 서로 다른 방법으로

처리하는게 가능해 집니다.


하지만, 이 예제에서는 만들어놓은 커스텀 에러 핸들러(사용자 정의 오류 처리기)를 모든 오류를 처리하도록 사용하도록 해보겠습니다:

set_error_handler("customError");

직접 만든 함수가 모든 오류를 처리하길 원했기 때문에

set_error_handler() 에는 오직 하나의 매개변수만 넣으면

됩니다.


두번째 매개변수는 에러 레벨을 명기하기 위해 추가될 수 있습니다.


예제

존재하지 않은 변수를 출력하려고 함으로서 에러 핸들러(오류 처리기)를 시험해 보도록 합시다:

<?php
//error handler function
function customError($errno, $errstr)
{
echo "<b>Error:</b> [$errno] $errstr";
}
//set error handler
set_error_handler("customError");
//trigger error
echo($test);
?>


위 코드의 출력 메시지는 아래와 같은 형태로 나와야 합니다:

Custom error: [8] Undefined variable: test



오류 발생시키기(Trigger an Error)

사용자가 데이터를 입력할 수 있는 스크립트에서는,

불법적인 입력이 발생했을때 오류를 발생시키는 것이 상당히 유용합니다.

PHP에서는, 이걸 trigger_error() 함수를 통해 실행 할 수 있습니다.


예제

이 예제에서는 "test" 변수가 "1"보다 클 경우에 오류가 발생합니다:

<?php
$test=2;
if ($test>1)
{
trigger_error("Value must be 1 or below");
}
?>


위 코드의 출력 결과는 아래와 같습니다:

Notice: Value must be 1 or below
in C:\webfolder\test.php on line 6

에러는 스크립트내애서 원하는 곳이라면 어디에서나 발생 시킬 수 있고,

두번째 매개변수를 추가함으로서 어떤 에러 레벨(오류 수준)이 발생되어야

하는지 서술할 수 있습니다.


가능한 에러 타입(오류 형태):

  • E_USER_ERROR - 사용자가 생성한 치명적 런타임 에러. 복구될 수 없는 에러들이 해당. 스크립트의 실행은 중지됨.
  • E_USER_WARNING - 사용자가 생성한 치명적이지 않은 런타임 경고. 스크립트의 실행은 중지되지 않음.
  • E_USER_NOTICE - 기본값. 사용자가 생성한 런타임 통지. 오류일수도 있지만, 스크립트가 일반적으로 실행중에도 발생할 수 있는 그런 형태의 에러.


예제

이 예제에서는 "test" 변수가 "1" 보다 크면 E_USER_WARNING가 발생하게 됩니다.

E_USER_WARNING 이 발생하게 되면

커스텀 에러 핸들러(사용자 정의 오류 처리기)를 이용하도록 하고

스크립트를 종료시킵니다:

<?php
//error handler function
function customError($errno, $errstr)
{
echo "<b>Error:</b> [$errno] $errstr<br />";
echo "Ending Script";
die();
}
//set error handler
set_error_handler("customError",E_USER_WARNING);
//trigger error
$test=2;
if ($test>1)
{
trigger_error("Value must be 1 or below",E_USER_WARNING);
}
?>
 


위 코드의 출력 결과는 아래와 같아야 합니다:

Error: [512] Value must be 1 or below
Ending Script

지금까지 어떻게 자신만의 에러를 만들고, 어떻게 그걸 발생시킬 수 있는지를

보셨습니다. 그럼 이젠, 오류 기록하기에 대해서 보도록 합시다.




오류 기록하기(Error Logging)

기본적으로 PHP는 php.ini 파일의 error_log 설정값이 어떻게 설정되어

있는지에 기반해서, 에러 로그(Error log)를 서버의 로깅 시스템이나 파일로

보냅니다.

error_log() 함수를 이용함으로서, 에러 로그를 지정된 파일이나

혹은 원격 목적지로 전송하는것이 가능합니다.


오류 메시지를 이메일을 통해 여러분 자신에게 전송하는 것은

특정 오류가 발생했는지 알게 될 수 있는 좋은 방법중 하나가

될 수 있습니다.


 

이메일(E-Mail)로 오류 메시지 전송하기

아래의 예제 에서는 특정 오류가 발생할 경우

에러 메시지가 담겨있는 이메일을 전송한 뒤 스크립트를 종료하도록 합니다:

<?php
//error handler function
function customError($errno, $errstr)
{
echo "<b>Error:</b> [$errno] $errstr<br />";
echo "Webmaster has been notified";
error_log("Error: [$errno] $errstr",1,
"someone@example.com","From: webmaster@example.com");
}
//set error handler
set_error_handler("customError",E_USER_WARNING);
//trigger error
$test=2;
if ($test>1)
{
trigger_error("Value must be 1 or below",E_USER_WARNING);
}
?>


위 코드의 출력물은 아래와 같을 겁니다:

Error: [512] Value must be 1 or below
Webmaster has been notified


그리고 위의 코드를 통해 받게된 메일 메시지는 아래와 같을 겁니다:

Error: [512] Value must be 1 or below

이 방법은 모든 오류에 대해 사용되어서는 안될 것입니다.

보통의 오류들은 PHP의 기본 로깅 시스템을 사용해서

서버상에 기록되어야 합니다.

 

출처 : http://sirjhswin.tistory.com/163