【PHP8.x】__constructメソッドの使い方

__constructメソッドの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

__constructメソッドは、PHP 8で導入されたSensitiveParameterValueクラスの新しいインスタンスを生成する際に実行されるコンストラクタメソッドです。このメソッドの主な役割は、セキュリティ上の理由から外部に漏らしたくない機密性の高い情報(パスワードやAPIキーなど)を、スタックトレースやデバッグ出力(例: var_dump())に直接表示させないように「ラップ」することです。

このコンストラクタは、単一の引数として、隠蔽したい実際の値を受け取ります。受け取った値は、内部的にSensitiveParameterValueオブジェクトとして保持され、通常の出力からは内容が見えないように匿名化されます。通常、この__constructメソッドが直接開発者のコードから呼び出されることは稀です。多くの場合、#[SensitiveParameter]属性が関数やメソッドの引数に指定されている場合、その引数に渡された値はPHPの内部処理によって自動的にSensitiveParameterValueオブジェクトに変換され、このコンストラクタが暗黙的に利用されます。

これにより、例えばエラー発生時に出力されるスタックトレースに機密情報が誤って含まれてしまうといった事態を防ぎ、アプリケーションのセキュリティレベルを向上させることができます。開発者が明示的に特定の値を機密として扱いたい場合には、このコンストラクタを直接呼び出してSensitiveParameterValueオブジェクトを作成し、値をラップすることも可能です。この機能は、機密情報の取り扱いをより安全に行うためのPHP 8の重要な改善点の一つです。

構文(syntax)

1<?php
2
3$secretData = "私のパスワード123";
4$sensitiveValue = new SensitiveParameterValue($secretData);
5
6?>

引数(parameters)

mixed $value

  • mixed $value: センシティブな値として保持されるデータ。型は任意。

戻り値(return)

戻り値なし

戻り値はありません

サンプルコード

PHP 8 コンストラクタプロパティプロモーションと機密情報隠蔽

1<?php
2
3/**
4 * SensitiveParameterValue は、PHP 8.2 で導入されたクラスで、
5 * スタックトレース(エラー発生時の呼び出し履歴)に表示される可能性のある機密情報を隠蔽するために使用されます。
6 * そのコンストラクタ `__construct(mixed $value)` は、隠蔽したい値をラップします。
7 *
8 * このサンプルコードでは、PHP 8 の「コンストラクタプロパティプロモーション」と組み合わせて、
9 * SensitiveParameterValue の使用方法を示します。
10 * コンストラクタプロパティプロモーションは、コンストラクタの引数を直接クラスのプロパティとして定義できる機能です。
11 */
12class UserAccount
13{
14    // コンストラクタプロパティプロモーションを使用してプロパティを定義します。
15    // 引数 $username は公開プロパティ $username として直接宣言されます。
16    // 引数 $password は、機密情報として SensitiveParameterValue のインスタンスとして受け取り、
17    // private プロパティ $password として直接宣言されます。
18    public function __construct(
19        public string $username,
20        private SensitiveParameterValue $password // SensitiveParameterValue オブジェクトをプロモートされたプロパティとして定義
21    ) {
22        // コンストラクタプロパティプロモーションを使用しているため、
23        // ここで $this->username = $username; や $this->password = $password; を書く必要はありません。
24    }
25
26    /**
27     * ユーザー名を取得します。
28     * @return string
29     */
30    public function getUsername(): string
31    {
32        return $this->username;
33    }
34
35    /**
36     * ラップされたパスワードオブジェクト (SensitiveParameterValue) を取得します。
37     * 実際のパスワード文字列は取得しません。
38     * @return SensitiveParameterValue
39     */
40    public function getPasswordObject(): SensitiveParameterValue
41    {
42        return $this->password;
43    }
44
45    /**
46     * 実際のパスワード文字列を取得します。
47     * このメソッドは、内部処理でのみ使用されるべきであり、セキュリティ上の注意が必要です。
48     * @return mixed
49     */
50    public function getActualPasswordValue(): mixed
51    {
52        return $this->password->getValue();
53    }
54}
55
56// UserAccount クラスのインスタンスを作成します。
57// パスワードは SensitiveParameterValue クラスのインスタンスとしてコンストラクタに渡されます。
58// ここで SensitiveParameterValue::__construct('mySuperSecretPassword123!') が呼び出されます。
59$user = new UserAccount(
60    'alice_smith',
61    new SensitiveParameterValue('mySuperSecretPassword123!')
62);
63
64echo "--- ユーザーアカウント情報 ---" . PHP_EOL;
65echo "ユーザー名: " . $user->getUsername() . PHP_EOL;
66
67// SensitiveParameterValue オブジェクトを var_dump すると、
68// 内部の機密値は `(redacted)` と表示され、直接公開されません。
69echo "パスワードオブジェクト (var_dump): " . PHP_EOL;
70var_dump($user->getPasswordObject());
71
72// UserAccount オブジェクト全体を var_dump した場合も同様に、機密値は redacted されます。
73echo "UserAccount オブジェクト全体 (var_dump): " . PHP_EOL;
74var_dump($user);
75
76// 実際のパスワード値にアクセスするには、`SensitiveParameterValue::getValue()` メソッドを呼び出す必要があります。
77// これは、特定の処理(例:パスワードの検証)で必要な場合にのみ行われるべきです。
78echo "実際のパスワード値: " . $user->getActualPasswordValue() . PHP_EOL;
79
80// (補足) もしこのコード内でエラーが発生し、スタックトレースが生成された場合、
81// `mySuperSecretPassword123!` という文字列はスタックトレースには表示されません。
82// これが SensitiveParameterValue の主な目的です。
83

PHP 8 の SensitiveParameterValue クラスは、スタックトレースに表示される可能性のある機密情報を隠蔽するために使用されます。そのコンストラクタである __construct(mixed $value) は、引数 $value で渡された隠蔽したい値を内部に保持し、値を返しません。

このサンプルコードでは、PHP 8 で導入された「コンストラクタプロパティプロモーション」という簡潔な記法と組み合わせて、SensitiveParameterValue の利用方法を示しています。UserAccount クラスでは、パスワードを SensitiveParameterValue のインスタンスとしてプロパティに定義しています。これにより、クラスのインスタンスを var_dump する際などに、パスワードの実際の文字列は (redacted) と表示され、誤って機密情報がログなどに記録されることを防ぎます。

もし実際のパスワード文字列が必要な場合は、SensitiveParameterValue オブジェクトの getValue() メソッドを明示的に呼び出す必要があります。これは、パスワードの検証など、特定の用途に限って慎重に行うべき操作です。この仕組みによって、開発者は機密情報の取り扱いにより注意を払うことができ、セキュリティ向上に貢献します。

このサンプルコードは、スタックトレースで機密情報を隠蔽するSensitiveParameterValueと、PHP 8で導入されたコンストラクタプロパティプロモーションを組み合わせています。SensitiveParameterValueは、エラー時の呼び出し履歴から機密値を隠すことが主な目的であり、メモリ上や他のログからの情報漏洩を防ぐものではない点に注意してください。getValue()メソッドで実際の値を取り出せるため、このメソッドの安易な使用はセキュリティリスクを高めます。パスワード検証など本当に必要な場面でのみ呼び出し、そのアクセス範囲も厳しく管理することが重要です。コンストラクタプロパティプロモーションでは、引数の可視性(public/private)がそのままプロパティの可視性となることも意識しましょう。

【PHP8.x】__constructメソッドの使い方 | いっしー@Webエンジニア