예외 클래스
Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 91개 중 66번째.
PHP에서 예외(exceptions)는 실행 중에 무언가 잘못되었음을 알리는 데 사용되는 객체입니다. 모든 예외의 기본 클래스는 Exception이며, 그 구조를 이해하면 OOP 애플리케이션에서 오류를 효과적으로 처리하는 데 도움이 됩니다.
예외를 던질 때, 무엇이 잘못되었는지 설명하는 메시지와 함께 Exception 클래스(또는 하위 클래스)의 인스턴스를 생성합니다:
<?php
class BankAccount {
public function __construct(private float $balance = 0) {}
public function withdraw(float $amount): float {
if ($amount > $this->balance) {
throw new Exception("Insufficient funds");
}
$this->balance -= $amount;
return $amount;
}
}
$account = new BankAccount(100);
$account->withdraw(150);
이것은 "Insufficient funds"라는 메시지와 함께 처리되지 않은 예외(uncaught exception) 오류를 발생시킵니다.
PHP는 다양한 상황에 대비해 여러 가지 내장 예외 클래스를 제공합니다. InvalidArgumentException은 잘못된 입력을 알리고, RuntimeException은 실행 중 발생하는 오류를 나타내며, LogicException은 프로그래밍 오류를 나타냅니다:
<?php
class Calculator {
public function divide(int $a, int $b): float {
if ($b === 0) {
throw new InvalidArgumentException("Cannot divide by zero");
}
return $a / $b;
}
}
모든 예외 객체는 유용한 정보를 담고 있습니다: getMessage()는 에러 메시지를 반환하며, getCode()는 선택적인 에러 코드를 반환하고, getFile() 및 getLine()은 예외가 발생한 위치를 알려줍니다. 특정 예외 유형을 사용하면 코드의 의도가 더 명확해지고 더 정밀한 에러 처리가 가능해집니다.
챌린지
쉬움PHP의 내장 예외 클래스를 사용하여 다양한 유형의 문제를 신호로 보내는 재고 관리 시스템을 구축해 보겠습니다. 작업이 구체적이고 의미 있는 방식으로 실패할 수 있는 제품 재고 시스템을 만들 것입니다.
코드는 세 개의 파일로 구성됩니다:
Product.php— 재고의 항목을 나타내는Product클래스를 생성합니다. 생성자 프로모션(constructor promotion)을 사용하여 public$sku(string), public$name(string), 그리고 private$quantity(int)를 정의합니다. 클래스에는 다음이 포함되어야 합니다:- 현재 수량을 반환하는
getQuantity(): int메서드 - 수량을 증가시키는
addStock(int $amount): void메서드. 만약 amount가 1보다 작으면,"Amount must be positive"라는 메시지와 함께InvalidArgumentException을 던집니다. - 수량을 감소시키는
removeStock(int $amount): void메서드. 만약 amount가 1보다 작으면,"Amount must be positive"라는 메시지와 함께InvalidArgumentException을 던집니다. 만약 amount가 현재 수량을 초과하면,"Insufficient stock"이라는 메시지와 함께RuntimeException을 던집니다.
- 현재 수량을 반환하는
Inventory.php— 제품 컬렉션을 관리하는Inventory클래스를 생성합니다. Product 파일을 포함(include)하세요. 클래스에는 다음이 포함되어야 합니다:- SKU를 키로 하여 제품을 저장하는 private 배열
- 제품을 추가하는
addProduct(Product $product): void메서드. 동일한 SKU를 가진 제품이 이미 존재하면,"Product already exists: [sku]"라는 메시지와 함께LogicException을 던집니다. - SKU로 제품을 반환하는
getProduct(string $sku): Product메서드. 제품을 찾을 수 없으면,"Product not found: [sku]"라는 메시지와 함께InvalidArgumentException을 던집니다.
main.php— Inventory 파일을 포함하세요. SKU, 제품 이름, 그리고 작업("add","remove", 또는"duplicate")의 세 가지 입력을 받습니다.Inventory를 생성하고 주어진 SKU, 이름, 초기 수량10을 가진 새로운Product를 추가합니다.작업에 따라 다음을 수행합니다:
"add": 제품의addStock(5)를 호출한 후,"Stock updated: [quantity]"를 출력합니다."remove": 제품의removeStock(15)를 호출합니다 (이 작업은 예외를 던져야 합니다)."duplicate": 동일한 SKU를 가진 다른 제품을 추가하려고 시도합니다 (이 작업은 예외를 던져야 합니다).
예외가 발생하면, 예외의 클래스 이름 뒤에
": "와 예외 메시지를 출력합니다. 클래스 이름을 가져오려면 PHP의get_class()함수를 사용하세요.
이 챌린지는 다양한 예외 유형이 잘못된 입력, 런타임 실패, 논리 오류 등 서로 다른 종류의 문제를 어떻게 전달하는지 보여주며, 코드의 에러 처리를 더 정밀하고 의미 있게 만들어 줍니다.
치트 시트
PHP에서 예외(exception)는 실행 중에 발생하는 오류를 알리는 객체입니다. 기본 클래스는 Exception입니다.
예외를 발생시키려면(throw), 설명이 포함된 메시지와 함께 인스턴스를 생성하세요:
<?php
class BankAccount {
public function __construct(private float $balance = 0) {}
public function withdraw(float $amount): float {
if ($amount > $this->balance) {
throw new Exception("Insufficient funds");
}
$this->balance -= $amount;
return $amount;
}
}
PHP는 다양한 상황에 맞는 내장 예외 클래스를 제공합니다:
InvalidArgumentException— 잘못된 입력을 알림RuntimeException— 실행 중 발생하는 오류를 나타냄LogicException— 프로그래밍 오류를 나타냄
<?php
class Calculator {
public function divide(int $a, int $b): float {
if ($b === 0) {
throw new InvalidArgumentException("Cannot divide by zero");
}
return $a / $b;
}
}
예외 객체는 유용한 메서드들을 제공합니다:
getMessage()— 오류 메시지를 반환함getCode()— 선택적인 오류 코드를 반환함getFile()— 예외가 발생한 파일을 반환함getLine()— 예외가 발생한 줄 번호를 반환함
예외 객체의 클래스 이름을 가져오려면 get_class()를 사용하세요.
직접 해보기
<?php
require_once 'Inventory.php';
// 입력 읽기
$sku = trim(fgets(STDIN));
$name = trim(fgets(STDIN));
$operation = trim(fgets(STDIN));
try {
// TODO: Inventory 생성
// TODO: 주어진 SKU, 이름, 초기 수량 10으로 Product 생성
// TODO: 인벤토리에 제품 추가
// TODO: 작업(operation)에 따라:
// - "add": 제품의 addStock(5)을 호출한 후, "Stock updated: [quantity]" 출력
// - "remove": 제품의 removeStock(15) 호출
// - "duplicate": 동일한 SKU를 가진 다른 제품 추가 시도
} catch (Exception $e) {
// TODO: 예외 클래스 이름 뒤에 ": "와 메시지를 이어서 출력
// 힌트: 클래스 이름을 가져오려면 get_class($e)를 사용하세요
}
?>이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
8매직 메서드
매직 메서드 소개__toString 및 __debugInfo__get, __set, __isset, __unset__call 및 __callStatic__clone 및 객체 복제__serialize 및 __unserialize요약 - 커스텀 컬렉션11타입 시스템과 에러 핸들링
타입 선언Nullable 타입유니온 및 인터섹션 타입예외 클래스커스텀 예외 계층 구조Try, Catch, Finally요약 - Form Validator