PHP 예외 처리

예외(Exception)는 지정된 오류가 발생할 때 스크립트의 정상적인 흐름을 변경하는 데 사용됩니다.

예외는 무엇인가요?

PHP 5는 새로운 객체 지향적 오류 처리 방법을 제공합니다.

예외 처리는 지정된 오류(예외)가 발생할 때 스크립트의 정상적인 흐름을 변경하는 데 사용됩니다. 이 상황을 예외라고 합니다.

예외가 발생할 때, 일반적으로 다음과 같이 발생합니다:

  • 현재 코드 상태가 저장됩니다
  • 코드 실행이 예약된 예외 처리기 함수로 전환됩니다
  • 상황에 따라 처리기는 저장된 코드 상태에서 코드를 다시 시작하거나 스크립트 실행을 종료하거나 코드의 다른 위치에서 스크립트를 계속 실행할 수 있습니다.

다양한 오류 처리 방법을 보여드리겠습니다:

  • 예외의 기본 사용
  • 사용자 정의 예외 처리기 생성
  • 여러 예외
  • 재발생 예외
  • 최상위 예외 처리기 설정

예외의 기본 사용

예외가 투げ뜨려지면, 그 이후의 코드는 계속 실행되지 않으며 PHP는 일치하는 "catch" 코드 블록을 찾으려고 시도합니다.

예외가 잡히지 않았고 set_exception_handler()를 사용하여 적절한 처리를 하지 않았다면, 심각한 오류(최종 오류)가 발생하고 "Uncaught Exception" (미취소된 예외) 오류 메시지가 출력됩니다.

다음과 같이 예외를 투げ던지고 동시에 그를 잡지 않으려고 시도해 보겠습니다:

<?php
//exception throwing function 생성
function checkNum($number)
 {
 if($number>1)
  {
  throw new Exception("값은 1 또는 그 이하여야 합니다");
  }
 return true;
 }
//exception trigger
checkNum(2);
?>

위의 코드는 다음과 같은 오류를 얻습니다:

최종 오류: 미취소된 예외 'Exception' 
message 'Value must be 1 or below' in C:\webfolder\test.php:6 
스택 트레이스: #0 C:\webfolder\test.php(12): 
checkNum(28) #1 {main} thrown in C:\webfolder\test.php on line 6

Try, throw 및 catch

위의 예제에서 발생하는 오류를 피하기 위해, 예외를 처리하는 적절한 코드를 생성해야 합니다.

정확한 처리 프로그램은 다음과 같아야 합니다:

  1. Try - 예외를 일으키는 함수는 "try" 코드 블록 내에 위치해야 합니다. 예외가 발생하지 않으면 코드가 일반적으로 계속 실행됩니다. 하지만 예외가 발생하면 예외가 투げ뜨려집니다.
  2. Throw - 여기서는 예외를 투げném하는 방법을 정의합니다. 각 "throw"은 최소한 하나의 "catch"와 일치해야 합니다
  3. Catch - "catch" 코드 블록은 예외를 잡고, 예외 정보를 포함한 객체를 생성합니다

그럼 예외를 투げném해 보겠습니다:

<?php
// 예외를 투げném할 수 있는 함수를 생성합니다
function checkNum($number)
 {
 if($number>1)
  {
  throw new Exception("값은 1 또는 그 이하여야 합니다");
  }
 return true;
 }
// "try" 코드 블록에서 예외를 투げném합니다
try
 {
 checkNum(2);
 // 예외가 투げném되면, 이 텍스트는 표시되지 않습니다
 echo '이를 볼 수 있다면, 숫자는 1 또는 그 이하입니다';
 }
// 예외를 잡기
catch(Exception $e)
 {
 echo 'Message: ' .$e->getMessage();
 }
?>

위 코드는 이와 같은 오류를 얻습니다:

Message: 값은 1 또는 그 이하여야 합니다

例子解释:

위 코드는 예외를 투げném하고, 그것을 잡습니다:

  1. checkNum() 함수를 생성합니다. 이 함수는 숫자가 1보다 크면 예외를 투げ뜁니다.
  2. "try" 코드 블록에서 checkNum() 함수를 호출합니다.
  3. checkNum() 함수에서 예외가 발생합니다
  4. "catch" 코드 블록이 이 예외를 받아들이고, 예외 정보를 포함한 객체 ($e)를 생성합니다.
  5. exception 객체에서 $e->getMessage()을 호출하여 이 예외의 오류 메시지를 출력합니다

그러나 “각 throw은 catch와 일치해야 한다”는 원칙을 따르기 위해, 누락된 오류를 처리하기 위해 최상위 예외 처리기를 설정할 수 있습니다.

사용자 정의 Exception 클래스를 생성하십시오

사용자 정의 예외 처리기를 생성하는 것은 매우 간단합니다. PHP에서 예외가 발생할 때 호출할 수 있는 특별한 클래스를 간단히 생성합니다. 이 클래스는 exception 클래스의 확장이어야 합니다.

이 개별적인 exception 클래스는 PHP의 exception 클래스의 모든 속성을 상속받습니다. 여기서는 사용자 정의 함수를 추가할 수 있습니다.

우리는 exception 클래스를 생성하기 시작합니다:

<?php
class customException extends Exception
 {
 public function errorMessage()
  {
  //error message
  $errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
  ': <b>'.$this->getMessage().'</b>는 유효한 이메일 주소가 아닙니다';
  return $errorMsg;
  }
 }
$email = "someone@example...com";
try
 {
 //check if 
 if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
  {
  //throw exception if email is not valid
  throw new customException($email);
  }
 }
catch (customException $e)
 {
 //display custom message
 echo $e->errorMessage();
 }
?>

이 새로운 클래스는 오래된 예외 클래스의 복사본으로 errorMessage() 함수가 추가되었습니다. 이 클래스가 복사본이기 때문에, 오래된 클래스에서 상속받은 속성과 메서드를 사용할 수 있습니다. 예를 들어 getLine(), getFile(), getMessage()와 같은 예외 클래스의 메서드를 사용할 수 있습니다.

例子解释:

위 코드는 예외를 던지고, 그 예외를 사용자 정의 예외 클래스로 잡습니다:

  1. customException() 类是作为旧的 exception 类的一个扩展来创建的。这样它就继承了旧类的所有属性和方法。
  2. errorMessage() 함수를 생성합니다. 이메일 주소가 불법적이면 이 함수는 오류 메시지를 반환합니다
  3. $email 변수를 불법적인 이메일 주소 문자열로 설정합니다
  4. "try" 코드 블록을 실행하면 이메일 주소가 불법적이기 때문에 예외가 발생합니다
  5. "catch" 코드 블록은 예외를 잡고 오류 메시지를 표시합니다

여러 예외

하나의 스크립트에 여러 예외를 사용하여 여러 가지 상황을 검사할 수 있습니다.

여러 if..else 코드 블록, 또는 하나의 switch 코드 블록, 또는 여러 예외를 중첩하여 사용할 수 있습니다. 이 예외들은 다른 예외 클래스를 사용하여 다른 오류 메시지를 반환할 수 있습니다:

<?php
class customException extends Exception
{
public function errorMessage()
{
//error message
$errorMsg = 'Error on line '.$this->getLine().' in '.$this->getFile()
': <b>'.$this->getMessage().'</b>는 유효한 이메일 주소가 아닙니다';
return $errorMsg;
}
}
$email = "someone@example.com";
try
 {
 //check if 
 if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE)
  {
  //throw exception if email is not valid
  throw new customException($email);
  }
 //check for "example" in mail address
 if(strpos($email, "example") !== FALSE)
  {
  throw new Exception("$email is an example e-mail");
  }
 }
catch (customException $e)
 {
 echo $e->errorMessage();
 }
catch(Exception $e)
 {
 echo $e->getMessage();
 }
?>

例子解释:

위 코드는 두 가지 조건을 테스트했으며, 어떤 조건도 성립하지 않으면 예외를 던집니다:

  1. customException() 类是作为旧的 exception 类的一个扩展来创建的。这样它就继承了旧类的所有属性和方法。
  2. 创建 errorMessage() 函数。如果 e-mail 地址不合法,则该函数返回一个错误消息。
  3. "try" 코드 블록을 실행하면 첫 번째 조건에서 예외가 발생하지 않습니다.
  4. e-mail이 "example" 문자열을 포함하고 있기 때문에 두 번째 조건이 예외를 발생시킵니다.
  5. "catch" 코드 블록은 예외를 잡고 적절한 오류 메시지를 표시합니다

customException을 잡지 못하고 base exception만 잡았다면, 그곳에서 예외를 처리합니다.

재발생 예외

어떤 경우에도 예외가 발생할 때, 표준 방식과 다른 방식으로 처리하고 싶을 수 있습니다. "catch" 코드 블록에서 예외를 다시 던질 수 있습니다.

스크립트는 사용자에게 시스템 오류를 숨기는 것이 좋습니다. 시스템 오류는 프로그래머에게 중요할 수 있지만, 사용자는 그들에 대해 관심이 없습니다. 사용자가 더 쉽게 사용할 수 있도록, 사용자에게 친화적인 메시지를 포함한 예외를 다시 던질 수 있습니다:

<?php
class customException extends Exception
 {
 public function errorMessage()
  {
  //error message
  $errorMsg = $this->getMessage().' is not a valid E-Mail address.';
  return $errorMsg;
  }
 }
$email = "someone@example.com";
try
 {
 try
  {
  //check for "example" in mail address
  if(strpos($email, "example") !== FALSE)
   {
   //throw exception if email is not valid
   throw new Exception($email);
   }
  }
 catch(Exception $e)
  {
  //re-throw exception
  throw new customException($email);
  }
 }
catch (customException $e)
 {
 //display custom message
 echo $e->errorMessage();
 }
?>

例子解释:

上面的代码检测在邮件地址中是否含有字符串 "example"。如果有,则再次抛出异常:

  1. customException() 类是作为旧的 exception 类的一个扩展来创建的。这样它就继承了旧类的所有属性和方法。
  2. 创建 errorMessage() 函数。如果 e-mail 地址不合法,则该函数返回一个错误消息。
  3. 把 $email 变量设置为一个有效的邮件地址,但含有字符串 "example"。
  4. "try" 代码块包含另一个 "try" 代码块,这样就可以再次抛出异常。
  5. 由于 e-mail 包含字符串 "example",因此触发异常。
  6. "catch" 捕获到该异常,并重新抛出 "customException"。
  7. 捕获到 "customException",并显示一条错误消息。

현재 "try" 코드 블록에서 예외가 잡히지 않았다면, 더 높은 레벨에서 catch 코드 블록을 찾을 것입니다.

톱 레벨 예외 처리기 설정

set_exception_handler() 함수는 모든 잡히지 않은 예외를 처리하는 사용자 정의 함수를 설정할 수 있습니다.

<?php
function myException($exception)
{
echo "<b>Exception:</b> " , $exception->getMessage();
}
set_exception_handler('myException');
throw new Exception('Uncaught Exception occurred');
?>

위의 코드의 출력은 다음과 같아야 합니다:

Exception: Uncaught Exception occurred

위의 코드에서 "catch" 코드 블록이 없으며, 대신 톱 레벨 예외 처리 프로그램이 트리거됩니다. 모든 잡히지 않은 예외를 잡기 위해 이 함수를 사용해야 합니다.

예외의 규칙

  • 예외 처리가 필요한 코드는 잠재적인 예외를 잡기 위해 try 코드 블록 내에 배치되어야 합니다.
  • 각각의 try 또는 throw 코드 블록은 적어도 하나의对应的 catch 코드 블록을 가져야 합니다.
  • 다양한 종류의 예외를 잡을 수 있는 여러 개의 catch 코드 블록을 사용할 수 있습니다.
  • catch 코드 블록 내에서는 다시 예외를 던질 수 있습니다(re-thrown).

간단히 말해서: 예외가 발생하면 반드시 잡아야 합니다.