Menu
Coddy logo textTech

예외 클래스

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()은 예외가 발생한 위치를 알려줍니다. 특정 예외 유형을 사용하면 코드의 의도가 더 명확해지고 더 정밀한 에러 처리가 가능해집니다.

challenge icon

챌린지

쉬움

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)를 사용하세요
}

?>
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨