PHP로 코딩을 하다보면 error가 발생했을 때, exit()이나 die()를 사용하는 코드를 많이 볼 수 있다. 만약 이런 코드들을 function으로 호출하고, 그 function에서 exit()이나 die()를 수행하면 이 에러 메시지를 받아서 다른 식으로 사용하는 코드를 구성할 수 있을까?
마치 다른 언어들에서 exception을 던지고, try ~ catch 구문에서 exception을 받아 에러 처리를 하는 방식처럼 구성할 수 있는지에 대한 의문이다.
물론 PHP에서도 exception과 try ~ catch를 사용할 수 있기 때문에, 코드를 익숙한 방식으로 수정할 수도 있지만 많은 PHP 코드에서 exit()과 die()를 사용하기에 한번쯤 짚고 넘어갈 필요가 있는 이슈로 판단되었다.
Contents
1. 배경
현재 수정하고 있는 워드프레스의 플러그인은 user가 Form의 내용을 입력하고, save 버튼을 누르는 경우 form의 action에 지정된 function에서 validation을 수행하고, validation에 문제가 없는 경우 save하는 형태로 코드가 구성되어 있다.
만약 validation에 실패하면 die(메시지)를 호출하고, 이 메시지는 javascript 코드에서 받아서 에러 창을 표시해주게 된다.
구조를 표현한 다이어그램 (수정 중)
그런데 위 구조에서 save하는 코드에 여러가지 다른 기능을 덧붙여서 기존 save 코드를 inner_save로 바꾸고, 새로운 save에서 inner_save의 die(메시지)를 catch해서 다른 방식으로 동작하도록 코딩할 수 있을지가 고민이었다.
2. 궁금한 포인트들
위와 같은 상황에서 코드를 수정하려고 하다보니 들었던 궁금한 점은 다음과 같다.
- die와 exit의 차이는 무엇인가 ? echo와 die를 섞어쓰는 경우는 ?
- inner_save에서 던진 die(메시지)를 catch할 수 있는가? (Exception 처럼)
이다. 하나씩 찾아보고 정리해보자.
3. die와 exit의 차이는 무엇인가 ?
둘은 똑 같다고 한다 !! 1
https://stackoverflow.com/questions/1795025/what-are-the-differences-in-die-and-exit-in-php
위 링크의 내용을 참고하면 C를 참고하며 exit을 가져오고, Perl을 참고하며 die를 가져왔는데 사실 2개는 동일하다는 설명이 있다.
4. Exit vs. Trigger Error vs. throw Exception
그렇다면 exit과 tigger error2, 그리고 exception은 어떤 차이가 있고, 언제 사용하는게 맞을까?
https://medium.com/@liamhammett/catching-an-exit-in-php-75e44f9384e6
https://stackify.com/php-error-handling-guide/
1) Exit (또는 die)
개발 단계에서 사용하고, 실제 운영 단계에서 사용하지 말라는 의견들이 있다. 에러를 exit 또는 die로 처리하는 방식은 Poor Design이라는 의견이다.
동작방식은 PHP Script의 실행을 중단시키고, Shutdown 함수와 클래스의 Destructor를 호출하고 실행을 종료한다. HTML 출력을 하고 있다면 끝까지 출력되지 않고, exit 호출 시점에서 php 실행이 종료된다. 3
하지만 위 배경에서 설명된 방법처럼, html 출력이 아닌 handler 코드에서 exit에 메시지를 싣어서 보내고, ajax 코드에서는 사용자에게 이 경고 메시지를 전달하는 방식은 많이들 사용하는 방법으로 보인다.
2) Trigger Error
trigger_error()와 set_error_handler를 사용하면 에러의 레벨4과 출력되는 방식들을 세부적으로 조정할 수 있다고 한다.
Debug 모드와 운영 모드 각각에 다른 error handler를 등록하여 운영 시 정제된 에러처리가 가능하도록 사용한다고 한다.
3) Exception
java 등 다른 언어에서 알고 있는 그 exception이다. 가장 무난한 방법으로 보인다.
아래 문서를 참고하자.
https://www.w3schools.com/php/php_exception.asp
5. exit를 메시지를 catch 하는 방식으로 사용할 수는 없는 걸까?
이미 많은 코드가 exit를 던지고 있다. 그렇다면 하나씩 exception으로 고치지 말고 exit에서 던진 메시지를 어디선가 받아서 에러 처리하는 방법은 없는 걸까?
아래 방법을 참고해보자.
https://stackoverflow.com/questions/3836524/can-i-catch-exit-and-die-messages
function onDie(){ $message = ob_get_contents(); // Capture 'Doh' ob_end_clean(); // Cleans output buffer callWhateverYouWant(); } register_shutdown_function('onDie'); //... ob_start(); // You need this to turn on output buffering before using die/exit @$dumbVar = 1000/0 or die('Doh'); // "@" prevent warning/error from php //... ob_end_clean(); // Remember clean your buffer before you need to use echo/print
코드가 가능할 것으로 보이지만, 굳이 위 방법을 따르지 않고 exception으로 수정하는 게 나아보인다. ^^;
Footnotes
- 그럼에도 exit()를 호출한 뒤에 반드시 die()를 호출하는 플러그인 코드들이 많이 있어서, 2개의 의미가 다를 거라고 생각해 왔었다.
- 사실 이번에 정리하며 처음 접했다.
- https://www.php.net/manual/en/function.exit.php
try … catch 구문에서 중간에 exit를 호출하면 finally 코드 역시 실행하지 않고 바로 종료된다. - E_USER *** 형태의 에러 타입을 지정할 수 있다.