Getter と Setter
CoddyのPHPジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 40/91。
アクセス修飾子について理解したところで、クラスの外部からプライベートプロパティと安全にやり取りするにはどうすればよいでしょうか?その答えは、ゲッターとセッター(getters and setters)です。これらは、プライベートデータへの制御されたアクセスを提供するパブリックメソッドです。
getterはプロパティの値を取得し、setterはそれを変更します。このパターンを使用すると、データがアクセスまたは変更される際にバリデーションやロジックを追加できます:
<?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()は空でない文字列のみを受け入れる必要があります。トリミング(trim)した後に文字列が空の場合は、プロパティを更新しないでください。setPrice()は 0 より大きい値のみを受け入れる必要があります。0 または負の価格は拒否してください。setStock()は 0 以上の値のみを受け入れる必要があります。負の在庫数は拒否してください。
"[name]: $[price] ([stock] in stock)"を返すパブリックメソッドgetInfo()を追加してください。main.php— Product ファイルをインクルードします。製品名、価格、在庫数、および更新用の新しい価格の4つの入力を受け取ります。Productインスタンスを作成し、セッターを使用して初期の名前、価格(floatに変換)、在庫(integerに変換)を割り当てます。getInfo()の結果を出力します。次に、新しい価格の値(floatに変換)で価格の更新を試み、再度getInfo()を出力します。最後に、在庫を-5(無効な値)に設定することを試み、在庫が変更されていないことを確認するためにもう一度getInfo()を出力します。
セッターはゲートキーパー(門番)として機能し、プライベートプロパティへの変更を許可する前に入力データを検証します。負の在庫のような無効なデータが渡された場合、セッターは単にそれを無視し、既存の有効な値をそのまま保持します。これがカプセル化の力です。外部のコードが何をしようとしても、オブジェクトはその整合性を維持します。
チートシート
ゲッターとセッターを使用して、プライベートプロパティへの制御されたアクセスを提供します。ゲッターは値を取得し、セッターはオプションのバリデーション(検証)を行って値を変更します:
<?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(); // john@example.com
echo $user->getAge(); // 25
セッターは、データを保存する前にバリデーションを行うことができます。バリデーションに失敗した場合、セッターは更新を無視し、既存の値をそのまま保持することができます。ゲッターのみを提供することで読み取り専用のプロパティを作成したり、セッターのみを提供することで書き込み専用のプロパティを作成したりできます。
自分で試してみよう
<?php
require_once 'Product.php';
// 入力を読み込む
$name = trim(fgets(STDIN));
$price = trim(fgets(STDIN));
$stock = trim(fgets(STDIN));
$newPrice = trim(fgets(STDIN));
// TODO: 新しいProductインスタンスを作成する
// TODO: セッターを使用して、初期の名前、価格(浮動小数点数)、在庫(整数)を割り当てる
// TODO: getInfo()の結果を出力する
// TODO: 価格をnewPrice(浮動小数点数)で更新し、再度getInfo()を出力する
// TODO: 在庫を-5(無効)に設定しようと試み、getInfo()を出力して在庫が変更されていないことを確認する
?>このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。