[PHP] 에러 페이지를 처리하는 방법 (추가: ob_clean함수와 die함수 사용법)


Study/PHP  2019. 9. 24. 22:37

안녕하세요. 명월입니다.


이 글은 PHP에서 에러 페이지를 처리하는 방법 (추가: ob_clean함수와 die함수 사용법)에 대한 글입니다.

예전에 제가 PHP 내에서 에러 처리를 하는 방법에 대해 작성한 적이 있습니다.

링크 - [PHP] Fatal 및 Notice, Warnig 에러 메시지 처리하는 방법


프로그램을 개발할 때에는 이 에러 메시지가 발생하고 그 잘못된 라인을 찾아서 수정을 해야합니다만, Production의 경우라면 다릅니다.

실제 인터넷상에서 서비스를 하는 프로그램이라고 하면 에러가 발생할 경우 그 에러를 숨겨야 합니다.

가장 좋은 것은 사실 애초에 에러를 발생하지 않게 작성하는게 최고의 방법입니다만, 사람이 만드는 일이다 보니 예상치도 못한 버그가 생길 수 있고, 모든 유저의 행동 패턴을 예측할 수 없기 때문에 에러가 필연적으로 발생합니다.


이런 에러 메시지를 숨겨야 하는 이유는 가장 큰 것은 실제 웹 서비스에 위에 시스템 로그가 보일 경우, 무언가 완성되지 않은 듯한 모습을 보이기 때문에 유저들에게 신뢰감을 많이 떨어지게 할 것입니다.

두번째는 에러 메시지 뿐이면 다행이지만, 시스템 정보 내용이라던가 소스 내용이 공개가 되면 공격의 표적이 될 수 있기 때문에 가려야 합니다.


이런 에러가 발생할 때 에러페이지로 전환을 해야하는데 그 전환하는 설정이 .htaccess에서 설정합니다.

링크 - [PHP] 분산 설정 파일(.htaccess) 사용법


에러 코드 - https://ko.wikipedia.org/wiki/HTTP_상태_코드

(에러 코드표를 참조하면서 확인하면 이해하기 쉽습니다.)


Options -MultiViews
RewriteEngine On
Options -Indexes
RewriteCond %{REQUEST_URI} !(.js$)
RewriteCond %{REQUEST_URI} !(.css$)
RewriteCond %{REQUEST_URI} !(.ico$)
RewriteRule ^(.*)$ index.php?htaccess=$1 [QSA,L]

# 404가 에러가 발생하면 /Error?code=404로 Rewrite실행한다.
ErrorDocument 404 /Error?code=404
<?php
  // GET 파라미터에 Error가 있으면 아래의 조건절이 구현된다.
  if(strtoupper($_GET["htaccess"]) == "ERROR"){
    // 파라미터 code를 취득한다.
    $code = $_GET["code"];
    // 파라미터 code가 없으면 $code 데이터를 404로 설정한다.
    if(trim($code) == ""){
      $code = "404";
    }
    // $code.php 즉, 404에러일 경우 404.php를 인크루드한다.
    @include($_SERVER["DOCUMENT_ROOT"]."/".$code.".php");
    // 구현을 멈춘다.
    die();
  }
?>
<!DOCTYPE html>
<html>
<head>
<title>title</title>
</head>
<body>
  Index.php
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>title</title>
</head>
<body>
  404 ERROR
</body>
</html>

일단 소스는 우리가 가장 잘 알고 있는 404에러 입니다. 정적 웹 서버에서의 404에러는 해당 페이지가 없을 때 발생하는 에러 코드입니다.

먼저 .htaccess를 보면 404에러가 발생하면 /Error?code=404 코드로 rewrite가 발생합니다.

그럼 Rewrite룰에 의해 Index.php?htaccess=Error&code=404로 변환이 되겠습니다. 그럼 index.php의 조건절의 의해 404.php가 읽어들어서 게시(Response)를 하는 로직입니다.

실제로 image폴더는 test파일이 존재하지 않습니다.

그렇기 때문에 404가 에러가 발생합니다. 404에러가 발생하면 index.php파일에서 404.php를 include되게 끔 구현이 됩니다.


이번에는 웹 서버에서 발생한 에러 코드가 아닌 소스 내부에서 발생하는 에러코드입니다.

<?php
  // 에러함수 호출
  function response_error($code) {
    // response http status를 $code로 호출한다.
    http_response_code($code);
    // 지금까지 읽었던 http body부분을 클리어한다.
    ob_clean();
    // $code.php 즉, 404에러일 경우 404.php를 인크루드한다.
    @include($_SERVER["DOCUMENT_ROOT"]."/".$code.".php");
    // 구현을 멈춘다.
    die();
  }
  // GET 파라미터에 Error가 있으면 아래의 조건절이 구현된다.
  if(strtoupper($_GET["htaccess"]) == "ERROR"){
    // 파라미터 code를 취득한다.
    $code = $_GET["code"];
    // 파라미터 code가 없으면 $code 데이터를 404로 설정한다.
    if(trim($code) == ""){
      $code = "404";
    }
    // $code.php 즉, 404에러일 경우 404.php를 인크루드한다.
    @include($_SERVER["DOCUMENT_ROOT"]."/".$code.".php");
    // 구현을 멈춘다.
    die();
  }
  // 파라미터 data를 취득한다.
  $data = $_GET["data"];
  // 데이터가 없으면
  if($data == null){
    // 404 에러 함수를 호출한다.
    response_error(404);
  }
?>
<!DOCTYPE html>
<html>
<head>
<title>title</title>
</head>
<body>
  <?=$data?>
</body>
</html>

위 소스는 제가 파리미터의 여부로 에러 페이지의 호출 구현을 하였습니다.

제가 GET 파라미터의 data의 데이터를 넣으니 Status Code는 200이 나오네요.. 200은 정상입니다. 그리고 웹 페이지에도 파라미터의 값 1이 표시됩니다.

그러나 GET 파라미터의 data의 데이터를 지우니 Status Code는 404이 나옵니다. 제가 위 소스에서 404로 리턴을 했으니 에러코드는 404로 나갑니다 만약 404가 아닌 400 코드를 넣었으면 400이 표시 될 것입니다. 400.php 파일은 없기 때문에.. 또 다른 버그가..

그리고 웹 페이지도 404.php가 제대로 호출되서 표시가 되네요.


제가 여기서 이 에러 페이지 처리를 위해 내장 함수를 두 개 썻습니다. ob_clean과 die입니다.

ob_clean는 PHP는 스크립트이기 때문에 Response를 읽어서 웹서버로 응답합니다. 그때 읽어 드릴때 버퍼에 그 String값을 넣어두는데 그 String값을 클리어 하는 함수입니다.

die는 PHP는 스크립트 진행을 멈추고 서버로 응답을 즉시 실시하는 함수 입니다.

링크 - https://www.php.net/manual/en/function.ob-clean.php

링크 - https://www.php.net/die


여기까지 PHP에서 에러 페이지를 처리하는 방법 (추가: ob_clean함수와 die함수 사용법)에 관한 설명이었습니다.


궁금한 점이나 잘못된 점이 있으면 댓글 부탁드립니다.