소개
PHP에서 Throwable 인터페이스는 Error 클래스와 Exception 클래스가 구현하고 있습니다. 모든 내장(built-in) Error 클래스는 Error 클래스를 상속하며, try 블록 안에서 해당 Error 객체가 던져지면 이어지는 적절한 catch 블록에서 처리됩니다.
예외 던지기의 기본 동작
try 블록 안에서 예외가 발생하지 않으면, 코드는 시퀀스에 정의된 마지막 catch 블록 다음부터 정상적으로 계속 실행됩니다. 반대로 예외가 던져지면 이후 코드는 건너뛰고, 가장 먼저 일치하는 catch 블록으로 제어가 넘어갑니다.
예제
<?php
function div($x, $y) {
if (!$y) {
throw new Exception('Division by zero.');
}
return $x/$y;
}
try {
echo div(10,5) . "\n";
echo div(10,0) . "\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
// Continue execution
echo "Execution continues\n";
?>출력 결과
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
2 Caught exception: Division by zero. Execution continues
예제에서 두 번째 호출인 div(10, 0)은 0으로 나누려다 Exception이 던져졌고, catch 블록이 이를 잡아 오류 메시지를 출력한 뒤 스크립트가 끝까지 실행된 것을 확인할 수 있습니다.
TypeError 예외 처리
다음 예제에서는 함수에 올바른 타입의 인수가 전달되지 않아 실행 과정에서 TypeError가 던져집니다. 그에 대응하는 오류 메시지가 화면에 표시됩니다.
예제
<?php
function add(int $num1, int $num2){
return $num1 + $num2;
}
try {
$value = add(1, 'one');
} catch (TypeError $e) {
echo $e->getMessage(). "\n";
}
?>출력 결과
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
Argument 2 passed to add() must be of the type integer, string given
add() 함수는 int 타입 파라미터를 선언하고 있으므로, 문자열 'one'이 전달되는 순간 PHP 엔진이 자동으로 TypeError를 발생시킵니다. 이처럼 타입 선언(type declaration)과 예외 처리를 함께 사용하면 더 견고한 코드를 작성할 수 있습니다.
SPL 표준 예외(SPL Exceptions)
PHP 표준 라이브러리(SPL)에는 용도별로 미리 정의된 예외 클래스들이 포함되어 있습니다. 상황에 맞는 예외를 선택해 사용하면 코드의 의도를 명확하게 전달할 수 있습니다.
| LogicException | 프로그램 로직 자체의 오류를 나타내는 예외입니다. |
| BadFunctionCallException | 콜백이 정의되지 않은 함수를 참조하거나, 필요한 인수가 일부 누락된 경우 발생하는 예외입니다. |
| BadMethodCallException | 콜백이 정의되지 않은 메서드를 참조하거나, 필요한 인수가 일부 누락된 경우 발생하는 예외입니다. |
| DomainException | 값이 정의된 유효 데이터 도메인(domain)을 따르지 않을 때 발생하는 예외입니다. |
| InvalidArgumentException | 전달된 인수가 기대한 타입이 아닐 때 발생하는 예외입니다. |
| LengthException | 길이 값이 유효하지 않을 때 발생하는 예외입니다. |
| OutOfRangeException | 허용 범위를 벗어난 잘못된 인덱스가 요청되었을 때 발생하는 예외입니다. |
| RuntimeException | 런타임에만 발견할 수 있는 오류가 발생했을 때 던져지는 예외입니다. |
| OutOfBoundsException | 값이 유효한 키(key)가 아닐 때 발생하는 예외입니다. |
| OverflowException | 가득 찬 컨테이너에 요소를 추가하려 할 때 발생하는 예외입니다. |
| RangeException | 프로그램 실행 중 범위(range) 오류를 나타내기 위해 발생하는 예외입니다. 언더플로/오버플로를 제외한 산술 오류에 해당합니다. |
| UnderflowException | 빈 컨테이너에 대해 요소 제거와 같은 유효하지 않은 연산을 수행할 때 발생하는 예외입니다. |
| UnexpectedValueException | 값이 기대한 값 집합과 일치하지 않을 때 발생하는 예외입니다. |
다음 예제는 PHP 배열에서 존재하지 않는 키를 조회하려 할 때 OutOfBoundsException이 던져지는 상황을 보여줍니다.
예제
<?php
$arr=array("one"=>1, "two"=>2,"three"=>3,"four"=>4);
$key="ten";
try{
if (array_key_exists($key, $arr)==FALSE){
throw new OutOfBoundsException("key not found");}
else {
echo $arr[$key];}
}
catch (OutOfBoundsException $e){
echo $e->getMessage(). "\n";
}
?>출력 결과
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
key not found
array_key_exists()로 키의 존재 여부를 검사한 후, 키가 없으면 직접 OutOfBoundsException을 던지고 catch 블록에서 메시지를 출력하는 방식입니다. 이처럼 SPL 예외를 활용하면 오류의 성격을 코드만으로도 명확히 표현할 수 있습니다.