오류 처리
CodeIgniter는 SPL collection 예외와 프레임워크에서 제공하는 몇 가지 예외를 통해 시스템에 오류 보고를 구축합니다.
환경 설정에 따라 오류 또는 예외가 발생했을 때의 기본 작업은 응용 프로그램이 production 환경에서 실행되지 않는 한 자세한 오류 보고서를 표시하는 것입니다. production 환경에서는 사용자에게 최상의 사용자 경험을 유지하기 위해 보다 일반적인 메시지가 표시됩니다.
예외 사용
이 섹션은 초보 프로그래머나 예외 사용 경험이 없는 개발자를 위한 빠른 개요입니다.
예외란 무엇입니까?
예외는 단순히 예외가 “발생”할 때 발생하는 이벤트입니다. 그러면 스크립트의 현재 흐름이 중단되고 해당 오류 페이지를 표시하는 오류 처리기로 실행이 전송됩니다.
<?php
throw new \Exception('Some message goes here');
예외 잡기
예외를 발생시킬 수 있는 메서드를 호출하는 경우 try/catch 블록을 사용하여 해당 예외를 포착할 수 있습니다.
<?php
try {
$user = $userModel->find($id);
} catch (\Exception $e) {
exit($e->getMessage());
}
$userModel에서 예외가 발생하면 예외가 포착되고 catch 블록 내의 코드가 실행됩니다. 이 예에서는 스크립트가 종료되고 UserModel이 정의한 오류 메시지가 표시됩니다.
특정 예외 잡기
위의 예에서는 모든 유형의 예외를 포착합니다. DataException과 같은 특정 유형의 예외만 감시하려면 catch 매개변수에 이를 지정할 수 있습니다. 발생하고 포착된 예외의 하위 클래스가 아닌 다른 모든 예외는 오류 핸들러로 전달됩니다.
<?php
use CodeIgniter\Database\Exceptions\DataException;
try {
$user = $userModel->find($id);
} catch (DataException $e) {
// do something here...
}
이는 오류를 직접 처리하거나 스크립트가 끝나기 전에 정리를 수행하는 데 유용할 수 있습니다. 오류 처리기가 정상적으로 작동하도록 하려면 catch 블록 내에서 새 예외를 발생시킬 수 있습니다.
<?php
use CodeIgniter\Database\Exceptions\DataException;
try {
$user = $userModel->find($id);
} catch (DataException $e) {
// do something here...
throw new \RuntimeException($e->getMessage(), $e->getCode(), $e);
}
설정
오류 보고
PHP ini 설정에서 display_errors이 활성화되면 CodeIgniter는 모든 오류와 함께 자세한 오류 보고서를 표시합니다.
따라서 기본적으로 CodeIgniter는 development 및 testing 환경에서 자세한 오류 보고서를 표시하고 production 환경에서는 오류를 표시하지 않습니다.
CI_ENVIRONMENT 변수를 설정하여 환경을 변경할 수 있습니다. 환경 설정을(를) 참조하세요.
중요
오류 보고를 비활성화해도 오류가 있는 경우 로그 기록이 중단되지 않습니다.
경고
.env 파일의 설정이 $_SERVER 및 $_ENV에 추가됩니다. 부작용으로 이는 자세한 오류 보고서가 표시되면 your secure credentials are publicly exposed을 의미합니다.
로깅 예외
기본적으로 “404 - 페이지를 찾을 수 없음” 예외를 제외한 모든 예외가 기록됩니다. app/Config/Exceptions.php의 $log 값을 설정하여 이 기능을 켜고 끌 수 있습니다.
<?php
namespace Config;
use CodeIgniter\Config\BaseConfig;
class Exceptions extends BaseConfig
{
// ...
public bool $log = true;
// ...
}
다른 상태 코드에 대한 로깅을 무시하려면 동일한 파일에서 상태 코드를 무시하도록 설정할 수 있습니다.
<?php
namespace Config;
use CodeIgniter\Config\BaseConfig;
class Exceptions extends BaseConfig
{
// ...
public array $ignoreCodes = [404];
// ...
}
참고
현재 Log settings이 모든 예외가 기록되는 critical 오류를 기록하도록 설정되지 않은 경우 예외에 대한 기록이 여전히 발생하지 않을 수 있습니다.
지원 중단 경고 로깅
Added in version 4.3.0.
v4.3.0 이전에는 error_reporting()에서 보고된 모든 오류가 ErrorException 개체로 발생했습니다.
그러나 PHP 8.1+ 사용이 급증하면서 많은 사용자가 passing null to non-nullable arguments of internal functions에 대해 예외가 발생하는 것을 볼 수 있습니다.
v4.3.0부터 PHP 8.1로의 마이그레이션을 쉽게 하기 위해 CodeIgniter에는 사용 중단 오류(E_DEPRECATED 및 E_USER_DEPRECATED)만 예외로 발생시키지 않고 기록하는 기능이 있습니다.
기본적으로 CodeIgniter는 개발 환경에서 예외를 발생시키지 않고 지원 중단만 기록합니다. 프로덕션 환경에서는 로깅이 수행되지 않으며 예외가 발생하지 않습니다.
설정
이 기능에 대한 설정은 다음과 같습니다. 먼저 Config\Exceptions 복사본이 두 가지 새로운 속성으로 업데이트되고 다음과 같이 설정되었는지 확인하세요.
<?php
namespace Config;
use CodeIgniter\Config\BaseConfig;
use Psr\Log\LogLevel;
class Exceptions extends BaseConfig
{
// ...
public bool $logDeprecations = true; // If set to false, an exception will be thrown.
// ...
public string $deprecationLogLevel = LogLevel::WARNING; // This should be one of the log levels supported by PSR-3.
// ...
}
다음으로, Config\Exceptions::$deprecationLogLevel에 설정한 로그 수준에 따라 Config\Logger::$threshold에 정의된 로거 임계값이 더 이상 사용되지 않는 로그 수준을 포함하는지 확인합니다. 그렇지 않은 경우 그에 따라 조정하십시오.
<?php
namespace Config;
use CodeIgniter\Config\BaseConfig;
class Logger extends BaseConfig
{
// ...
// This must contain the log level (5 for LogLevel::WARNING) corresponding to $deprecationLogLevel.
public $threshold = (ENVIRONMENT === 'production') ? 4 : 9;
// ...
}
그 이후에는 후속 지원 중단이 예외 없이 구성된 것으로 기록됩니다.
이 기능은 사용자 지원 중단에도 작동합니다.
<?php
@trigger_error('Do not use this class!', E_USER_DEPRECATED);
// Your logs should contain a record with a message like: "[DEPRECATED] Do not use this class!"
애플리케이션을 테스트하기 위해 항상 지원 중단을 적용할 수 있습니다. 환경 변수 CODEIGNITER_SCREAM_DEPRECATIONS을 진실한 값으로 설정하여 이를 구성할 수 있습니다.
프레임워크 예외
예외 디자인
v4.6.0부터 프레임워크가 발생하는 모든 예외 클래스는 다음과 같습니다.
CodeIgniter\Exceptions\ExceptionInterface구현CodeIgniter\Exceptions\LogicException또는CodeIgniter\Exceptions\RuntimeException확장
참고
프레임워크는 위 종류의 예외 클래스만 발생시키지만, 사용되는 PHP 또는 기타 라이브러리는 다른 예외를 발생시킬 수 있습니다.
프레임워크에서 발생하는 두 가지 기본 예외 클래스가 있습니다.
논리예외
CodeIgniter\Exceptions\LogicException은 \LogicException을 확장합니다. 이 예외는 프로그램 논리의 오류를 나타냅니다. 이러한 종류의 예외는 코드 수정으로 직접 이어집니다.
런타임예외
CodeIgniter\Exceptions\RuntimeException은 \RuntimeException을 확장합니다. 런타임에서만 발견할 수 있는 오류가 발생하면 이 예외가 발생합니다.
다음 프레임워크 예외도 사용할 수 있습니다.
PageNotFound예외
이는 404, 페이지를 찾을 수 없음 오류를 알리는 데 사용됩니다.
<?php
use CodeIgniter\Exceptions\PageNotFoundException;
$page = $pageModel->find($id);
if ($page === null) {
throw PageNotFoundException::forPageNotFound();
}
404 페이지의 기본 메시지 대신 표시될 예외에 메시지를 전달할 수 있습니다.
기본 404 보기 파일 위치는 HTTP 상태 코드 및 오류 보기을 참조하세요.
app/Config/Routing.php 또는 app/Config/Routes.php에서 404 오버라이드을 지정한 경우 표준 404 페이지 대신 호출됩니다.
구성 예외
이 예외는 구성 클래스의 값이 유효하지 않거나 구성 클래스가 올바른 유형이 아닌 경우 등에 사용해야 합니다.
<?php
throw new \CodeIgniter\Exceptions\ConfigException();
이는 종료 코드 3을 제공합니다.
데이터베이스예외
이 예외는 데이터베이스 연결을 생성할 수 없거나 일시적으로 끊어진 경우와 같은 데이터베이스 오류에 대해 발생합니다.
<?php
throw new \CodeIgniter\Database\Exceptions\DatabaseException();
이는 종료 코드 8을 제공합니다.
리디렉션예외
참고
v4.4.0부터 RedirectException의 네임스페이스가 변경되었습니다. 이전에는 CodeIgniter\Router\Exceptions\RedirectException이었습니다. v4.6.0에서는 이전 클래스가 제거되었습니다.
이 예외는 다른 모든 응답 라우팅을 무시하고 특정 URI로 강제로 리디렉션하는 것을 허용하는 특별한 경우입니다.
<?php
throw new \CodeIgniter\HTTP\Exceptions\RedirectException($uri);
$uri은 baseURL을 기준으로 한 URI 경로입니다. 기본값(302, “임시 리디렉션”) 대신 사용할 리디렉션 코드를 제공할 수도 있습니다.
<?php
throw new \CodeIgniter\HTTP\Exceptions\RedirectException($uri, 301);
또한 v4.4.0부터는 ResponseInterface를 구현하는 클래스의 객체를 첫 번째 인수로 사용할 수 있습니다. 이 솔루션은 응답에 추가 헤더나 쿠키를 추가해야 하는 경우에 적합합니다.
<?php
$response = service('response')
->redirect('https://example.com/path')
->setHeader('Some', 'header')
->setCookie('and', 'cookie');
throw new \CodeIgniter\HTTP\Exceptions\RedirectException($response);
예외에 HTTP 상태 코드 지정
Added in version 4.3.0.
v4.3.0부터 CodeIgniter\Exceptions\HTTPExceptionInterface을 구현하기 위해 Exception 클래스에 대한 HTTP 상태 코드를 지정할 수 있습니다.
HTTPExceptionInterface을 구현하는 예외가 CodeIgniter의 예외 핸들러에 의해 포착되면 예외 코드는 HTTP 상태 코드가 됩니다.
HTTP 상태 코드 및 오류 보기
예외 핸들러는 HTTP 상태 코드(있는 경우)에 해당하는 오류 보기를 표시합니다.
예를 들어 PageNotFoundException은 HTTPExceptionInterface을 구현하므로 해당 예외 코드 404는 HTTP 상태 코드가 됩니다. 따라서 이 오류가 발생하면 시스템은 웹 요청일 때 app/Views/errors/html 폴더에 error_404.php을 표시합니다. CLI를 통해 호출되면 시스템은 app/Views/errors/cli 폴더에 error_404.php을 표시합니다.
HTTP 상태 코드에 해당하는 뷰 파일이 없으면 production.php 또는 error_exception.php이 표시됩니다.
참고
PHP ini 설정에서 display_errors이 켜져 있으면 error_exception.php이 선택되고 자세한 오류 보고서가 표시됩니다.
사이트의 app/Views/errors/html 폴더에 있는 모든 오류 보기를 사용자 정의해야 합니다.
특정 HTTP 상태 코드에 대한 오류 보기를 생성할 수도 있습니다. 예를 들어 “400 Bad Request”에 대한 오류 보기를 생성하려면 error_400.php을 추가합니다.
경고
해당 HTTP 상태 코드가 포함된 오류 보기 파일이 존재하는 경우 예외 처리기는 환경에 관계없이 해당 파일을 표시합니다. 뷰 파일은 프로덕션 환경에서 자체적으로 자세한 오류 메시지를 표시하지 않도록 구현해야 합니다.
예외에 종료 코드 지정
Added in version 4.3.0.
v4.3.0부터 CodeIgniter\Exceptions\HasExitCodeInterface을 구현하기 위해 Exception 클래스의 종료 코드를 지정할 수 있습니다.
HasExitCodeInterface을 구현하는 예외가 CodeIgniter의 예외 핸들러에 의해 포착되면 getExitCode() 메서드에서 반환된 코드가 종료 코드가 됩니다.
사용자 정의 예외 처리기
Added in version 4.4.0.
예외 표시 방법을 더 자세히 제어해야 하는 경우 이제 자체 처리기를 정의하고 적용 시기를 지정할 수 있습니다.
새 핸들러 정의
첫 번째 단계는 CodeIgniter\Debug\ExceptionHandlerInterface을 구현하는 새 클래스를 만드는 것입니다. CodeIgniter\Debug\BaseExceptionHandler을(를) 확장할 수도 있습니다. 이 클래스에는 기본 예외 처리기에서 사용되는 여러 유틸리티 메서드가 포함되어 있습니다. 새 핸들러는 단일 메소드인 handle()를 구현해야 합니다.
<?php
namespace App\Libraries;
use CodeIgniter\Debug\BaseExceptionHandler;
use CodeIgniter\Debug\ExceptionHandlerInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Throwable;
class MyExceptionHandler extends BaseExceptionHandler implements ExceptionHandlerInterface
{
// You can override the view path.
protected ?string $viewPath = APPPATH . 'Views/exception/';
public function handle(
Throwable $exception,
RequestInterface $request,
ResponseInterface $response,
int $statusCode,
int $exitCode,
): void {
$this->render($exception, $statusCode, $this->viewPath . "error_{$statusCode}.php");
exit($exitCode);
}
}
이 예에서는 일반적으로 필요한 최소 코드 양을 정의합니다. 즉, 보기를 표시하고 적절한 종료 코드로 종료합니다. 그러나 BaseExceptionHandler은 다양한 다른 도우미 함수와 개체를 제공합니다.
새 처리기 구성
CodeIgniter에게 새 예외 처리기 클래스를 사용하도록 지시하는 것은 app/Config/Exceptions.php 구성 파일의 handler() 메서드에서 수행됩니다.
<?php
namespace Config;
use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Debug\ExceptionHandler;
use CodeIgniter\Debug\ExceptionHandlerInterface;
use Throwable;
class Exceptions extends BaseConfig
{
// ...
public function handler(int $statusCode, Throwable $exception): ExceptionHandlerInterface
{
return new ExceptionHandler($this);
}
}
애플리케이션이 예외를 처리해야 하는지 여부를 결정하는 데 필요한 모든 논리를 사용할 수 있지만 가장 일반적인 두 가지 방법은 HTTP 상태 코드 또는 예외 유형을 확인하는 것입니다. 클래스가 이를 처리해야 하는 경우 해당 클래스의 새 인스턴스를 반환합니다.
<?php
namespace Config;
use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Debug\ExceptionHandlerInterface;
use CodeIgniter\Exceptions\PageNotFoundException;
use Throwable;
class Exceptions extends BaseConfig
{
// ...
public function handler(int $statusCode, Throwable $exception): ExceptionHandlerInterface
{
if (in_array($statusCode, [400, 404, 500], true)) {
return new \App\Libraries\MyExceptionHandler($this);
}
if ($exception instanceof PageNotFoundException) {
return new \App\Libraries\MyExceptionHandler($this);
}
return new \CodeIgniter\Debug\ExceptionHandler($this);
}
}