예외라는 말은 프로그램 실행 도중 예상치 않은 동작이나 불확실한 처리로 발생할 수 있는 부분을 예상하여 오류까지도 같이 처리를 하는 코딩 방법입니다. try{} catch {}의 문법과 별도의 예외 처리를 위한 클래스 등이 존재합니다.
예외 처리는 PHP스크립트가 실행하면서 오류가 발생했을 때 처리할 수 있는 로직을 만들어 넣을 수 있는 기술입니다. 예외 처리 개념은 PHP 5.x 이전에는 도입되지 않았습니다.
오류의 경우는 프로그램의 문제가 발생하면 오류를 통보하고 프로그램이 중단됩니다. 하지만, 예외는 갑작스러운 오류 발생 시 스크립트를 그냥 종료하는 것이 아니라 별도의 처리 루틴을 통해 안전하게 프로그램을 마칠 수 있도록 합니다.
PHP는 예외 처리를 위해서 특별한 Exception 클래스를 제공합니다. 예외 처리 클래스는 예외 발생 시 심각한 오류를 안전한 경로로 우회하여 처리할 수 있도록 도와줍니다.
예외 처리 클래스 Exception도 new 키워드를 통해 인스턴스를 생성하여 사용할 수 있습니다. Exception 클래스는 오류 코드와 메시지를 전달하고 값을 처리할 수 있는 추가 메서드를 지원합니다.
예제 파일 exception-01.php
<?php
$msg = "예외 클래스 오류 발생";
$code = 444;
$e = new Exception($msg,$code);
echo "예외 코드 = ".$e->getCode();
echo "<br>";
echo "예외 메시지 = ".$e->getMessage();
?>
결과
예외 코드 = 444
예외 메시지 = 예외 클래스 오류 발생
예외 Exception 클래스 구조와 인터페이스는 다음과 같습니다.
Exception {
/* Properties */
protected string $message ;
protected int $code ;
protected string $file ;
protected int $line ;
/* Methods */
public __construct ([ string $message = "" [, int $code = 0 [, Throwable $previous = NULL ]]] )
final public string getMessage ( void )
final public Throwable getPrevious ( void )
final public mixed getCode ( void )
final public string getFile ( void )
final public int getLine ( void )
final public array getTrace ( void )
final public string getTraceAsString ( void )
public string __toString ( void )
final private void __clone ( void )
}
예외 처리가 발생하면 PHP 엔진은 Exception 클래스로 예외를 발생한 부분을 처리하게 됩니다.
PHP 7.x에서는 Exception 클래스는 throwable 인터페이스를 따릅니다.
Throwable {
/* Methods */
abstract public string getMessage ( void )
abstract public int getCode ( void )
abstract public string getFile ( void )
abstract public int getLine ( void )
abstract public array getTrace ( void )
abstract public string getTraceAsString ( void )
abstract public Throwable getPrevious ( void )
abstract public string __toString ( void )
}
throw 키워드를 이용하여 사용자가 직접 예외를 발생할 수 있습니다. 예외가 발생하면 PHP는 코드 실행을 중지됩니다.
throw 키워드는 Exception과 관련 서브 클래스에서만 사용이 가능한 키워드입니다.
예제 파일 exception-02.php
<?php
throw new Exception("강제적 예외 발생");
?>
결과
[Sun May 14 16:21:35 2017] ::1:55806 [500]: /jinyphp/exception-02.php - Uncaught Exception: 강제적 예외 발생 in C:\php-7.1.4-Win32-VC14-x86\jinyphp\exception-02.php:2
Stack trace:
#0 {main}
thrown in C:\php-7.1.4-Win32-VC14-x86\jinyphp\exception-02.php on line 2
위의 예제는 예외 발생 처리 예입니다. throw 명령으로 사용자가 직접 예외를 발생할 수 있습니다.
예외 처리 Exception 클래스를 상속받아 새로운 에외 처리 클래스를 직접 만들어서 사용할 수도 있습니다. 새로운 예외 처리는 클래스는 기존의 exception 함수를 상속받아서 생성을 합니다.
|문법|
class divException extends exception {}
예제 파일 exception-03.php
<?php
class aaaEx extends exception
{
public function showErr($msg)
{
echo $msg;
}
}
$msg = "예외 클래스 오류 발생";
$code = 444;
$e = new aaaEx($msg,$code);
$e->showErr("Exception을 상속합니다.");
echo "<br>";
echo "예외코드 = ".$e->getCode();
echo "<br>";
echo "예외메시지 = ".$e->getMessage();
?>
결과
Exception을 상속합니다.
예외 코드 = 444
예외 메시지 = 예외 클래스 오류 발생
위의 예제는 예외 처리 클래스 상속에 대한 예입니다. 기존 exception 예외 클래스를 상속받아 새로운 예외 처리 클래스를 만들어서 사용할 수 있습니다.
개발자는 예외 처리에 대해서 수동적인 방어 보다는 능동적인 방어가 필요합니다. 적극적으로 예외가 발생될 것을 예측하여 프로그램 코드를 작성해야 합니다.
PHP 언어는 예외를 포착할 수 있는 try ~ catch 명령 키워드를 제공합니다. try~catch는 C++이나 Java 등에서 일찌감치 예외 처리를 위해 사용하던 문법입니다. PHP 5.x 이후부터는 이와 비슷한 스타일로 예외 처리 문장을 만들 수 있습니다.
프로그램이 동작할 때 예외가 발생할 가능성이 있다고 하면 try {} catch {} 명령으로 예외 발생을 대비하는 것이 좋습니다.
try~catch는 2개의 영역으로 나누어져 있습니다.
|문법|
try {
예외가 발생할 가능성이 있는 내용들을 코딩합니다.
} catch (클래스명 $변수명) {
예외가 발생될 경우 처리할 내용들
}
try { } 부분
try 본문 안에는 예외가 발생될 가능성이 높은 코드를 작성하는 영역입니다. 특별한 코드가 이니라 정상적으로 수행하고자 하는 코드를 작성합니다. 만일 이 코드들이 예외를 발생할 여지가 있는 경우 try{} 로 코드를 감싸서 실행하는 것입니다.
오류 예외가 발생되지 않으면 큰 문제나 의미 없이 코드가 실행될 것입니다. 만일 try 안에 있는 코드에 예외가 발생하면 코드 실행을 중단하게 됩니다. 그리고 catch 부분의 코드를 수행합니다.
catch {} 부분
catch (클래스명 $변수명) { }은 try{} 본문에 예외가 포착되었을 때 처리되는 내용들입니다.
예외가 발생할 때 Excetion 클래스를 통해 예외 상태나 메시지를 받아올 수 있습니다. Exception 클래스는 예외를 처리할 수 있는 다양한 프로퍼티와 메서드를 가지고 있습니다.
|문법|
catch(Exception $err){
echo $err->getMessage();
}
예외 발생 시 Exception 클래스로 생성된 인스턴스를 받습니다. 생성된 인스턴스로 Exception 메서드를 실행할 수 있습니다.
예제 파일 exception-04.php
<?php
try {
throw new Exception("강제적 예외 발생");
} catch(Exception $err){
// Try {} 부분에 연산 오류로 인하여 예외 처리가 발생됨
echo "예외 처리 발생 :".$err->getMessage();
}
?>
결과
예외 처리 발생: 강제적 예외 발생
위의 예제는 try~catch 동작에 대한 예입니다. try {} 본문 안에서 강제적으로 throw 명령을 통해 개발자가 직접 예외를 발생합니다. 예외가 발생되면catch{} 안의 내용이 실행됩니다. catch 실행 시 예외 처리 클래스 exception 객체를 동시에 생성하여 catch 내부로 전달합니다.
catch 내에서는 exception 클래스로 생성된 객체를 접근하여 메시지 및 상태를 체크할 수 있습니다.
만일 예외 처리의 유형이 다양한 경우 catch를 연결하여 사용 가능합니다.
|문법|
try {
예외가 발생할 가능성이 있는 내용들을 코딩합니다.
} catch (클래스명 $변수명) {
예외가 발생될 경우 처리할 내용들
} catch (클래스명 $변수명) {
예외가 발생될 경우 처리할 내용들
}
catch는 위의 표현처럼 계속 체인 형태로 연결하여 사용할 수 있습니다.
예제 파일 exception-05.php
<?php
try {
$servername = "localhost";
$dbname = "testDB";
$username = "jiny";
$pasword = "abcd1234";
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
} catch (PDOException $e) {
echo "PDO 오류";
} catch (Exception $e) {
echo "일반예외";
}
?>
결과
PDO 오류
위의 예제는 다수의 catch 처리를 위한 실험입니다. 예외가 발생되면 예외 상태에 따라서 상항별로 catch 로 분기하여 처리됩니다.
finally { } 부분은 PHP 5.5에서 도입된 기능으로 try 부분이나 catch부분 처리가 끝나고 처리할 내용을 추가로 정의할 수 있습니다. finally {}는 독립적으로 사용을 할 수 없고 반드시 try ~ catch문 뒤에 소속되어 사용 가능합니다. 즉, 종속된 기능 명령어 입니다.
사용 문법
try {
예외가 발생할 가능성이 있는 내용들을 코딩합니다.
} catch (클래스명 $변수명) {
예외가 발생될 경우 처리할 내용들
} finally {
예외 발생 여부와 상관없이 처리할 내용
}
예제 파일 exception-06.php
<?php
try {
throw new Exception("강제적 예외 발생");
} catch(Exception $err){
// Try {} 부분에 연산오류로 인하여 예외 처리가 발생됨
echo "예외 처리 발생 :".$err->getMessage();
} finally {
// try {} 또는 catch(){} 부분의 처리 후에 처리가 됩니다.
echo "<br>";
echo "finally 연산 종료";
}
?>
결과
예외 처리 발생: 강제적 예외 발생
finally 연산 종료
위의 예제는 final 에 대한 예입니다. 예외가 발생하면 catch 부분을 수행합니다. 그리고 catch 부분을 처리 후에 finally {} 부분을 실행합니다.
try~catch로 처리하지 못한 예외가 있을 수도 있습니다. 이런 경우 전역 예외 처리를 통해 예상치 못한 예외도 포착할 수 있습니다.
|관련함수|
callable set_exception_handler ( callable $exception_handler )
set_exception_handler(); 내장 함수를 통하여 전역 예외 처리를 등록할 수 있습니다.
|관련함수|
bool restore_exception_handler ( void )
restore_exception_handler(); 내장 함수는 설정한 전역 처리기를 복원합니다.
예제 파일 exception-07.php
<?php
// 전역 예외 처리기를 등록합니다.
set_exception_handler(function(Exception $e){
echo "전역 예외 처리 포착<br>";
echo "예외 메시지 = ".$e->getMessage();
});
throw new Exception("강제적 예외 발생");
// 설정한 전역 처리기를 복원합니다.
restore_exception_handler();
?>
결과)
전역 예외 처리 포착
예외 메시지 = 강제적 예외 발생
위의 예제는 전역 예외 처리에 대한 예입니다. set_exception_handler() 함수를 통해 적역 예외 처리 함수를 등록합니다.