Menu
Coddy logo textTech

復習 - カスタムコレクション

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

challenge icon

チャレンジ

簡単

この章で学んだすべてのマジックメソッドをまとめた Collection クラスを作成しましょう。コレクションは柔軟なデータコンテナとして自然に使えるようにします。キーによる項目の保存、存在確認、動的な項目検索、独立したコピーの作成を行います。

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

  • Collection.php: 項目を private な array に保存する Collection class を作成します。コレクションでは、次のマジックメソッドが連携して動作する必要があります。
    • __construct(): 初期項目の optional な array を受け取ります(default は空の array)
    • __get($key): 指定されたキーの項目を返します。存在しない場合は null を返します
    • __set($key, $value): 指定されたキーに値を保存します
    • __isset($key): コレクション内にキーが exists するかどうかを返します
    • __unset($key): 指定されたキーの項目を削除します
    • __call($method, $args): dynamic な finder メソッドを処理します。findBy で始まるメソッド(findByRolefindByStatus など)が calling された場合、field 名("findBy" の後の部分を lowercase にしたもの)を extract し、すべての項目を検索して、その field が最初の argument と一致する最初の項目のキーを返します。一致する項目が見つからない場合は null を返します。それ以外のメソッドの場合は "Unknown method: [method]" を返します
    • __toString(): 項目数が count の "Collection([count] items)" を返します
    • __clone(): cloned されたとき、items array は fresh な copy(original への reference ではない)にします
  • main.php: Collection ファイルを include します。3つの入力、つまりキー名、role 値、search role を受け取ります。ユーザーのコレクションを作成し、すべてのマジックメソッドを実演します。
    • 新しい Collection を Create します
    • 入力キーを使ってユーザーを Add し、"name" にはキーを、"role" には入力された role 値を設定した array を保存します
    • キー "bob" で another ユーザーを Add し、["name" => "Bob", "role" => "editor"] を保存します
    • isset() を使って入力キーが exists するかどうかを Print します。出力は "exists" または "missing" です
    • search role を argument として dynamic な findByRole() メソッドを calling した結果を Print します(matching するユーザーのキーを返します。null の場合は何も返しません)
    • echo を使ってコレクションを Print します(__toString が trigger されます)
    • コレクションを Clone し、その後 clone から入力キーを unset します
    • original のコレクション内に入力キーが exists するかどうかを Print します。出力は "exists" または "missing" です(clone は independent なので、キーは引き続き exists するはずです)

各出力はそれぞれ独立した行にしてください。dynamic finder は、コレクション内の各項目が "name""role" のような field を持つ associative array であることを前提とします。

自分で試してみよう

<?php

require_once 'Collection.php';

// 入力を読み取る
$keyName = trim(fgets(STDIN));
$roleValue = trim(fgets(STDIN));
$searchRole = trim(fgets(STDIN));

// TODO: 新しい Collection を作成する

// TODO: 入力キーでユーザーを追加し、"name" => key と "role" => roleValue の配列を格納する

// TODO: キー "bob" で別のユーザーを追加し、["name" => "Bob", "role" => "editor"] を格納する

// TODO: isset() を使って入力キーが存在するかどうかを出力する - "exists" または "missing" を出力

// TODO: searchRole を引数として findByRole() を呼び出した結果を出力する

// TODO: echo を使ってコレクションを出力する(__toString をトリガーする)

// TODO: コレクションをクローンし、その後クローンから入力キーを unset する

// TODO: オリジナルのコレクションに入力キーが存在するかどうかを出力する - "exists" または "missing"

?>

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

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