Menu
Coddy logo textTech

例外クラス

CoddyのPHPジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 66/91。

PHPでは、例外は実行中に何か問題が発生したことを示すために使用されるオブジェクトです。すべての例外の基底クラスは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」を含むキャッチされない例外エラーが発生します。

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;
    }
}

すべてのexceptionオブジェクトには有用な情報が含まれています。getMessage()はエラーmessageを返し、getCode()はオプションのエラーコードを返し、getFile()getLine()はexceptionがスローされた場所を示します。特定のexception型を使用すると、コードの意図がより明確になり、より正確なエラー処理が可能になります。

challenge icon

チャレンジ

簡単

PHP 組み込みの例外クラスを使用して、さまざまな種類の問題を通知する在庫管理システムを構築しましょう。操作が具体的で意味のある方法で失敗する可能性のある商品在庫を作成します。

コードを 3 つのファイルに分けて整理します。

  • Product.php: 在庫内の商品を表す Product class を Create します。public $sku(string)、public $name(string)、private $quantity(int)には constructor promotion を使用します。class には次のものを含めます。
    • current quantity を返す getQuantity(): int method
    • quantity を増やす addStock(int $amount): void method。amount が 1 未満の場合、message "Amount must be positive"InvalidArgumentException を throw します
    • quantity を減らす removeStock(int $amount): void method。amount が 1 未満の場合、message "Amount must be positive"InvalidArgumentException を throw します。amount が current quantity を超える場合、message "Insufficient stock"RuntimeException を throw します
  • Inventory.php: 商品の collection を管理する Inventory class を Create します。Product file を include します。class には次のものを含めます。
    • SKU で indexed された商品を保存する private array
    • 商品を追加する addProduct(Product $product): void method。同じ SKU の商品が already exists する場合、message "Product already exists: [sku]"LogicException を throw します
    • SKU で商品を返す getProduct(string $sku): Product method。found されない場合、message "Product not found: [sku]"InvalidArgumentException を throw します
  • main.php: Inventory file を include します。3 つの inputs、SKU、商品名、そして operation("add""remove"、または "duplicate")を受け取ります。

    Inventory を Create し、given の SKU、name、initial quantity 10 を持つ新しい Product を追加します。

    operation Based on:

    • "add": 商品に対して addStock(5) を Call し、その後 "Stock updated: [quantity]" を print します
    • "remove": 商品に対して removeStock(15) を Call します(これは exception を throw するはずです)
    • "duplicate": 同じ SKU を持つ another product の追加を試みます(これは exception を throw するはずです)

    exception が throw された場合、exception の class name、その後に ": "、そして exception の message を print します。class name を取得するには PHP の get_class() function を使用します。

この challenge は、さまざまな exception type が、invalid input、runtime failures、logic errors など、異なる種類の問題をどのように伝えるかを示します。これにより、コードの error handling がより precise で meaningful になります。

自分で試してみよう

<?php

require_once 'Inventory.php';

// 入力を読み取る
$sku = trim(fgets(STDIN));
$name = trim(fgets(STDIN));
$operation = trim(fgets(STDIN));

try {
    // TODO: Inventoryを作成する
    // TODO: 指定されたSKU、name、初期数量10でProductを作成する
    // TODO: 製品をインベントリに追加する
    
    // TODO: 操作に基づいて:
    // - "add": Call addStock(5) on the product, then print "Stock updated: [quantity]"
    // - "remove": 製品に対してremoveStock(15)を呼び出す
    // - "duplicate": 同じSKUの別の製品を追加しようとする
    
} catch (Exception $e) {
    // TODO: 例外のクラス名の後に": "とメッセージを出力する
    // Hint: クラス名を取得するにはget_class($e)を使用する
}

?>
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: PHPオンラインコンパイラ