Getter と Setter
CoddyのPHPジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 40/91。
アクセス修飾子を理解したところで、クラスの外部からプライベートプロパティと安全にやり取りするにはどうすればよいでしょうか?その答えは、ゲッターとセッター(getters and setters)です。これらは、プライベートデータへの制御されたアクセスを提供するパブリックメソッドです。
ゲッターはプロパティの値を取得し、セッターはそれを変更します。このパターンにより、データがアクセスされたり変更されたりする際に、バリデーションやロジックを追加することができます。
<?php
class User {
private string $email;
private int $age;
public function getEmail(): string {
return $this->email;
}
public function setEmail(string $email): void {
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
$this->email = $email;
}
}
public function getAge(): int {
return $this->age;
}
public function setAge(int $age): void {
if ($age >= 0 && $age <= 150) {
$this->age = $age;
}
}
}
$user = new User();
$user->setEmail("john@example.com");
$user->setAge(25);
echo $user->getEmail() . "\n";
echo $user->getAge();
出力:
john@example.com
25セッターは、値を保存する前にメールの形式を検証し、年齢が妥当であることを確認します。セッターがないと、誰でも無効なデータを直接代入できてしまいます。また、ゲッターのみを提供することで読み取り専用プロパティを作成したり、セッターのみを提供することで書き込み専用プロパティを作成したりすることもできます。
重要なポイント: ゲッターとセッターを使用すると、プライベートデータへのアクセスや変更方法を制御でき、バリデーション、フォーマット、または任意のカスタムロジックを適用できるようになります。
チャレンジ
簡単ゲッターとセッターを使用して製品データを保護および検証する、製品在庫システムを構築しましょう。価格が常に正であり、在庫数が決して負にならないことを保証する Product クラスを作成します。これは、セッターがどのようにビジネスルールを強制できるかを示すデモンストレーションです。
コードを2つのファイルに分けて構成します:
Product.php— 3つのプライベートプロパティ$name(string)、$price(float)、$stock(integer) を持つProductクラスを作成します。各プロパティに対して、以下の検証ルールを持つゲッターとセッターを実装してください:setName()は空でない文字列のみを受け入れる必要があります。トリミング後に文字列が空の場合は、プロパティを更新しないでください。setPrice()は 0 より大きい値のみを受け入れる必要があります。0 または負の価格は拒否してください。setStock()は 0 以上の値のみを受け入れる必要があります。負の在庫数は拒否してください。
"[name]: $[price] ([stock] in stock)"を返すパブリックメソッドgetInfo()を追加してください。main.php— Product ファイルをインクルードします。製品名、価格、在庫数、および更新用の新しい価格の4つの入力を受け取ります。Productインスタンスを作成し、セッターを使用して初期の名前、価格(floatに変換)、在庫(integerに変換)を割り当てます。getInfo()の結果を出力します。次に、新しい価格の値(floatに変換)で価格の更新を試み、再度getInfo()を出力します。最後に、在庫を-5(無効な値) に設定しようと試み、在庫が変更されていないことを確認するためにもう一度getInfo()を出力します。
セッターはゲートキーパーとして機能し、プライベートプロパティへの変更を許可する前に入力データを検証します。負の在庫のような無効なデータが渡された場合、セッターは単にそれを無視し、既存の有効な値をそのまま保持します。これがカプセル化の力です。外部のコードが何をしようとしても、オブジェクトはその整合性を維持します。
自分で試してみよう
<?php
require_once 'Product.php';
// 入力を読み込む
$name = trim(fgets(STDIN));
$price = trim(fgets(STDIN));
$stock = trim(fgets(STDIN));
$newPrice = trim(fgets(STDIN));
// TODO: 新しい Product インスタンスを作成する
// TODO: セッターを使用して、初期の name、price(float型)、および stock(int型)を割り当てる
// TODO: getInfo() の結果を出力する
// TODO: price を newPrice(float型)で更新し、再び getInfo() を出力する
// TODO: stock に -5(無効な値)を設定しようと試み、getInfo() を出力して stock が変更されていないことを確認する
?>このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。