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

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

作成日: 更新日:

基本的な使い方

__constructメソッドは、新しいWeakReferenceインスタンスを初期化するメソッドです。WeakReferenceは、PHP 8で導入されたクラスで、オブジェクトへの「弱い参照」を作成するために使用されます。通常の変数のようにオブジェクトを参照すると、そのオブジェクトはメモリに保持され続け、ガベージコレクタによって解放されることはありません。しかし、WeakReferenceを使うと、参照先のオブジェクトが他の強い参照を持たなくなった場合、ガベージコレクタはそのオブジェクトをメモリから解放することができます。

この__constructメソッドは、WeakReferenceオブジェクトを生成する際に呼び出され、引数として、弱い参照を作成したいオブジェクトを一つ受け取ります。例えば、new WeakReference($myObject)のように使用します。これにより、$myObjectへの弱い参照が内部的に保持されたWeakReferenceインスタンスが作成されます。このインスタンスを通じて、参照先のオブジェクトがまだメモリ上に存在するかどうかを確認したり、存在すればそのオブジェクトを取得したりすることが可能になります。オブジェクトがガベージコレクタによって解放された場合、WeakReferenceは自動的にその参照を失い、get()メソッドはnullを返します。この機能は、キャッシュやイベントリスナーの実装など、オブジェクトのライフサイクル管理においてメモリ効率を高めるのに役立ちます。

構文(syntax)

1<?php
2
3public function __construct(object $object)
4
5?>

引数(parameters)

object $object

  • object $object: 保持するオブジェクト

戻り値(return)

戻り値なし

戻り値はありません

サンプルコード

PHP WeakReference::__constructで弱い参照を作成する

1<?php
2
3// 弱い参照が指すことができるクラスを定義します。
4// このクラスは、インスタンスが作成・破棄されたときにメッセージを表示します。
5class User
6{
7    public string $name;
8
9    public function __construct(string $name)
10    {
11        $this->name = $name;
12        echo "ユーザー '{$this->name}' が作成されました。\n";
13    }
14
15    public function __destruct()
16    {
17        echo "ユーザー '{$this->name}' が破棄されました。\n";
18    }
19}
20
21// 1. 参照されるオブジェクト(強い参照)を作成します。
22$user = new User("Alice");
23
24// 2. WeakReferenceのコンストラクタ(__construct) を使用して、
25//    $userオブジェクトへの弱い参照を作成します。
26//    $weakRef = new WeakReference($object) の形式で呼び出されます。
27//    この参照は$userオブジェクトの参照カウントを増やしません。
28$weakRef = new WeakReference($user);
29
30echo "\n--- 最初の状態 ---\n";
31// 弱い参照がまだオブジェクトを指しているか確認します。
32// get()メソッドは、オブジェクトが生きていればそのオブジェクトを、そうでなければnullを返します。
33if ($weakRef->get()) {
34    echo "弱い参照は現在、ユーザー: " . $weakRef->get()->name . " を指しています。\n";
35} else {
36    echo "弱い参照はオブジェクトを指していません。\n";
37}
38
39// 3. 元のオブジェクトへの強い参照を解除します。
40//    $userオブジェクトへの強い参照がすべてなくなると、PHPのガベージコレクタによって
41//    オブジェクトがメモリから解放される対象となります。
42unset($user);
43echo "元の強い参照が解除されました。\n";
44
45// 通常、ガベージコレクションはPHPが自動的に行いますが、
46// テスト目的で明示的にサイクルガベージコレクタを実行します。
47// (実際のアプリケーションでは、ほとんどの場合、明示的な呼び出しは不要です)
48gc_collect_cycles();
49
50echo "\n--- 強い参照解除後 ---\n";
51// 強い参照が解除され、オブジェクトが破棄された後、
52// 弱い参照がまだオブジェクトを指しているか確認します。
53// オブジェクトが破棄されていれば、$weakRef->get() は null を返します。
54if ($weakRef->get()) {
55    echo "弱い参照はまだオブジェクト: " . $weakRef->get()->name . " を指しています。\n";
56} else {
57    echo "弱い参照はオブジェクトを指していません。(オブジェクトが破棄されました)\n";
58}
59
60?>

PHPのWeakReference::__constructは、指定されたオブジェクトへの「弱い参照」を作成するためのコンストラクタです。通常の変数によるオブジェクト参照が「強い参照」と呼ばれ、オブジェクトがメモリから解放されないように参照カウントを増やすのに対し、「弱い参照」はオブジェクトの参照カウントを増やしません。これにより、弱い参照が存在してもオブジェクトの寿命には影響を与えないという特徴があります。

このコンストラクタにはobject $objectという引数が必要で、これは弱い参照の対象としたいオブジェクトそのものです。戻り値は特にありません。

サンプルコードでは、Userクラスのインスタンスをまず「強い参照」として作成し、次にWeakReference::__constructを用いてそのUserオブジェクトへの「弱い参照」を作ります。その後、元の「強い参照」を解除すると、オブジェクトはガベージコレクションの対象となり破棄されます。すると、それまで有効だった「弱い参照」も自動的に無効となり、get()メソッドでオブジェクトを取得しようとするとnullが返されることが確認できます。これは、メモリ管理においてオブジェクトの寿命を制御しながら、必要に応じて一時的にオブジェクトを参照したい場合に役立つ機能です。

WeakReferenceのコンストラクタは、引数として渡されたオブジェクトへの「弱い参照」を作成します。この参照は、元のオブジェクトの寿命を延ばすための参照カウントには影響を与えません。そのため、元となるオブジェクトへの強い参照がすべて解除されると、PHPのガベージコレクタによってオブジェクトがメモリから解放される対象となります。

サンプルコードでgc_collect_cycles()を明示的に呼び出しているのは、ガベージコレクションの動作を理解しやすくするためです。実際のアプリケーションでは、PHPが自動的にガベージコレクションを行うため、この関数を明示的に呼び出すことはほとんどありません。オブジェクトが破棄された後、弱い参照からはアクセスできなくなるため、WeakReference::get()メソッドがnullを返します。オブジェクトが存在するかどうかを常に確認し、nullチェックを行うことが重要です。

PHP 8 WeakReferenceとコンストラクタプロモーション

1<?php
2
3/**
4 * 弱い参照の対象となるオブジェクトの例。
5 * オブジェクトが破棄されたことを示すために、__destruct メソッドを含みます。
6 */
7class MyReferencedObject
8{
9    public string $id;
10
11    public function __construct(string $id)
12    {
13        $this->id = $id;
14        echo "MyReferencedObject '{$this->id}' が作成されました。\n";
15    }
16
17    public function __destruct()
18    {
19        echo "MyReferencedObject '{$this->id}' が破棄されました。\n";
20    }
21}
22
23/**
24 * PHP 8のコンストラクタプロパティプロモーションと WeakReference の使用例。
25 * このクラスは、別のオブジェクトへの弱い参照を保持します。
26 */
27class WeakReferenceContainer
28{
29    /**
30     * PHP 8のコンストラクタプロパティプロモーションを使用し、
31     * WeakReference のインスタンスをプライベートプロパティとして定義・初期化します。
32     *
33     * @param WeakReference $weakRef 保持する WeakReference インスタンス。
34     */
35    public function __construct(private WeakReference $weakRef)
36    {
37        // プロパティプロモーションにより、コンストラクタ本体はシンプルに保たれます。
38    }
39
40    /**
41     * 指定されたオブジェクトへの弱い参照を持つ WeakReferenceContainer の新しいインスタンスを生成します。
42     *
43     * @param object $objectToRefer 弱く参照する対象のオブジェクト。
44     * @return self 新しい WeakReferenceContainer のインスタンス。
45     */
46    public static function create(object $objectToRefer): self
47    {
48        // WeakReference::__construct を使用して、指定されたオブジェクトへの弱い参照を作成します。
49        // PHP 8 では WeakReference のコンストラクタが public になりました。
50        return new self(new WeakReference($objectToRefer));
51    }
52
53    /**
54     * 弱い参照が指すオブジェクトを取得します。
55     * オブジェクトがまだメモリ上に存在すればそのオブジェクトを、
56     * すでにガベージコレクションされていれば null を返します。
57     *
58     * @return object|null 参照されているオブジェクト、または null。
59     */
60    public function getReferencedObject(): ?object
61    {
62        return $this->weakRef->get();
63    }
64}
65
66// --- サンプルコードの実行 ---
67
68echo "--- 1. オブジェクトの作成と弱参照の保持 ---\n";
69// 1. 強参照を持つオブジェクトを作成します。
70$myObject = new MyReferencedObject("Data-123");
71
72// 2. WeakReferenceContainer を作成し、myObject への弱い参照を保持させます。
73//    この時、WeakReferenceContainer::create() メソッド内で WeakReference::__construct が呼び出され、
74//    WeakReferenceContainer のコンストラクタではプロパティプロモーションが利用されています。
75$container = WeakReferenceContainer::create($myObject);
76
77echo "WeakReferenceContainer は現在、オブジェクトを弱参照しています。\n";
78if ($container->getReferencedObject() !== null) {
79    echo "弱参照からオブジェクトを取得: ID " . $container->getReferencedObject()->id . "\n";
80} else {
81    echo "弱参照はオブジェクトを保持していません。\n";
82}
83
84echo "\n--- 2. 元のオブジェクトへの強参照を解除 ---\n";
85// 3. 元のオブジェクト ($myObject) への強参照を解除します。
86//    これにより、他にこのオブジェクトへの強参照が存在しなければ、
87//    オブジェクトはガベージコレクションの対象になります。
88unset($myObject);
89echo "元のオブジェクト ($myObject) への強参照を解除しました。\n";
90
91// 注意: PHPのガベージコレクションは非決定的であり、いつ実行されるかは保証されません。
92
93echo "\n--- 3. 弱参照の状態を確認 ---\n";
94// 4. 弱参照からオブジェクトを再取得しようとします。
95//    オブジェクトがガベージコレクションされていれば null が返されます。
96if ($container->getReferencedObject() === null) {
97    echo "弱参照はオブジェクトを保持していません(オブジェクトはガベージコレクションされた可能性が高いです)。\n";
98} else {
99    echo "弱参照はまだオブジェクトを保持しています(ガベージコレクションがまだ行われていない可能性があります)。\n";
100    echo "再取得したオブジェクトID: " . $container->getReferencedObject()->id . "\n";
101}
102
103echo "\n--- サンプルコード終了 ---\n";
104
105?>

WeakReference::__constructは、PHP 8で導入された、オブジェクトへの「弱い参照」を作成するためのコンストラクタです。通常の参照(強参照)と異なり、弱い参照は参照先のオブジェクトがメモリから解放(ガベージコレクション)されるのを妨げません。これにより、オブジェクトの生存期間に影響を与えずに参照を保持したい場合に利用されます。

引数としてobject $objectを受け取ります。この引数には、弱く参照したいオブジェクトのインスタンスを渡します。コンストラクタであるため、特定の戻り値はありません。新しいWeakReferenceインスタンスを初期化し、指定されたオブジェクトへの弱い参照を保持するよう設定します。

サンプルコードでは、WeakReferenceContainer::create()メソッド内でnew WeakReference($objectToRefer)として呼び出され、$objectToReferへの弱い参照が作成されています。作成された弱い参照は、get()メソッドを通じて参照先のオブジェクトを取得できますが、元のオブジェクトへの強参照が全て解除され、ガベージコレクションが実行されると、get()nullを返すようになります。

また、サンプルコードのWeakReferenceContainerクラスのコンストラクタでは、PHP 8で追加された「コンストラクタプロパティプロモーション」が利用されており、プロパティの定義と初期化を同時に行うことでコードを簡潔にしています。このWeakReferenceを活用することで、キャッシュの実装や循環参照の回避など、メモリ管理の高度な制御が必要な場面でリソースを効率的に利用する設計が可能になります。

WeakReferenceは、オブジェクトへの「弱い参照」を保持するための機能です。強参照が他に存在しなくなった場合、オブジェクトは自動的にメモリから解放されますが、WeakReferenceはそれを妨げません。__constructにはオブジェクトのみを渡してください。get()メソッドで弱い参照先のオブジェクトを取得できますが、参照先のオブジェクトが既に破棄されている可能性もあるため、常にnullチェックを行う必要があります。PHP 8のコンストラクタプロパティプロモーションは、コンストラクタ引数で直接プロパティを宣言し初期化できるため、コードを簡潔に書けます。また、ガベージコレクションの実行タイミングは不定であるため、強参照を解除してもすぐにオブジェクトが破棄されるとは限らない点も理解しておきましょう。

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