Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】WeakMap::offsetSet()メソッドの使い方

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

作成日: 更新日:

基本的な使い方

offsetSetメソッドは、PHP 8で追加されたWeakMapクラスに、オブジェクトをキーとして、それに対応する値を設定するために実行するメソッドです。WeakMapは、従来の配列やMapとは異なり、「弱い参照」という特殊な仕組みを持っています。

このメソッドを使うことで、WeakMapインスタンスに $weakmap[$object] = $value; のような配列形式で、キーとなるオブジェクトと関連する値をペアとして格納できます。ここでキーとして指定できるのは、必ずオブジェクトである必要があります。数値や文字列などのスカラー値をキーにすることはできません。

WeakMapの最大の特長は、キーとして設定されたオブジェクトが、このWeakMap以外からどこからも参照されなくなった場合、PHPの内部的なメモリ管理システムによって、そのオブジェクトがメモリから自動的に解放されると同時に、WeakMap内からも該当するキーと値のペアが削除される点にあります。

offsetSetメソッドを用いてデータを格納することで、アプリケーションが不要になったオブジェクトのデータを自動的にクリーンアップし、メモリの消費量を最適化することができます。これにより、メモリリークのリスクを減らし、より効率的なメモリ管理を実現します。特に、一時的なキャッシュデータなど、オブジェクトの生存期間に依存する情報の管理に非常に有用です。

構文(syntax)

1<?php
2
3$weakMap = new WeakMap();
4$keyObject = new stdClass();
5$value = 'データ';
6
7$weakMap[$keyObject] = $value;

引数(parameters)

object $object, mixed $value

  • object $object: WeakMap でキーとして使用するオブジェクト
  • mixed $value: $object に関連付ける値

戻り値(return)

void

offsetSetメソッドは、指定したキーに関連付けられた値をWeakMapに追加または更新します。このメソッドには戻り値はありません。

サンプルコード

PHP WeakMap offsetSet/offsetUnset入門

1<?php
2
3/**
4 * WeakMap::offsetSet と WeakMap::offsetUnset の使用例を示す関数。
5 *
6 * システムエンジニアを目指す初心者が WeakMap でのキーと値の設定、
7 * および削除の基本的な操作を理解するのに役立ちます。
8 * WeakMap はオブジェクトをキーとして使用し、ArrayAccess インターフェースを実装しているため、
9 * 配列のようにアクセスできます。
10 */
11function demonstrateWeakMapOperations(): void
12{
13    echo "--- WeakMap::offsetSet と WeakMap::offsetUnset のデモンストレーション ---" . PHP_EOL;
14
15    // 1. WeakMap のインスタンスを生成します。
16    // WeakMap はオブジェクトをキーとしてのみ使用できる特別なマップです。
17    $weakMap = new WeakMap();
18    echo "WeakMap を作成しました。" . PHP_EOL;
19
20    // 2. キーとなるオブジェクトを生成します。
21    // WeakMap のキーは常にオブジェクトである必要があります。
22    $keyObject = new stdClass();
23    $keyObject->id = 1001;
24    echo "キーとなるオブジェクト (stdClass, ID: {$keyObject->id}) を作成しました。" . PHP_EOL;
25
26    // 3. WeakMap::offsetSet メソッドを使って値を設定します。
27    // このメソッドは `$weakMap[$keyObject] = $value;` と同じ動作をします。
28    $valueToStore = 'これはオブジェクトに関連付けられたデータです。';
29    $weakMap->offsetSet($keyObject, $valueToStore);
30    echo "WeakMap に offsetSet メソッドで値を設定しました。" . PHP_EOL;
31
32    // 4. 設定された値が存在するか確認します。
33    // `$weakMap->offsetExists($keyObject)` は `isset($weakMap[$keyObject])` と同じです。
34    if ($weakMap->offsetExists($keyObject)) {
35        echo "WeakMap に値が存在します。取得された値: " . $weakMap[$keyObject] . PHP_EOL;
36    } else {
37        echo "エラー: 値が WeakMap に見つかりません。" . PHP_EOL;
38    }
39
40    echo PHP_EOL;
41
42    // 5. WeakMap::offsetUnset メソッドを使って値を削除します。
43    // このメソッドは `unset($weakMap[$keyObject]);` と同じ動作をします。
44    echo "WeakMap から offsetUnset メソッドで値を削除します。" . PHP_EOL;
45    $weakMap->offsetUnset($keyObject);
46
47    // 6. 削除されたことを確認します。
48    if (!$weakMap->offsetExists($keyObject)) {
49        echo "WeakMap から値が正常に削除されました。" . PHP_EOL;
50    } else {
51        echo "エラー: 値が WeakMap にまだ存在します。" . PHP_EOL;
52    }
53
54    echo "--- デモンストレーション終了 ---" . PHP_EOL;
55}
56
57// 上記の関数を実行してデモンストレーションを開始します。
58demonstrateWeakMapOperations();

PHP 8で導入されたWeakMapクラスは、オブジェクトをキーとして値を格納できる特別なマップです。一般的な配列とは異なり、キーとして指定したオブジェクトがプログラム上のどこからも参照されなくなった場合、WeakMap内のそのエントリは自動的に削除される「弱い参照」という特性を持っています。WeakMapArrayAccessインターフェースを実装しているため、配列のように直感的な記法でアクセス可能です。

WeakMap::offsetSetメソッドは、このWeakMapに新しいキーと値のペアを設定するために使用されます。このメソッドは、キーとなるobject $objectと、それに対応するmixed $valueを引数に取ります。戻り値はvoidであり、何も返しません。実質的には $weakMap[$object] = $value; という配列の代入文と同じ動作をします。

対照的に、WeakMap::offsetUnsetメソッドは、指定したキー(オブジェクト)に対応する値をWeakMapから削除します。引数には、削除したいキーとなるobject $objectを指定します。こちらも戻り値はvoidです。このメソッドは unset($weakMap[$object]); と書くのと同様に、WeakMapから特定のキーと関連する値のペアを取り除きます。

提供されたサンプルコードでは、WeakMapインスタンスを作成し、stdClassのオブジェクトをキーとして使用しています。まずoffsetSetを用いてキーオブジェクトに値を関連付け、その後にoffsetUnsetを用いてその関連付けを解除する一連の流れが示されており、それぞれの操作がoffsetExistsで正しく反映されているかを確認しています。これらのメソッドは、WeakMapの基本的なデータ操作を直接実行するための重要な手段です。

WeakMap::offsetSetWeakMap::offsetUnsetを利用する際の最も重要な点は、キーとして必ずオブジェクトを使用しなければならないことです。文字列や数値などのプリミティブ型はキーにはできませんので注意が必要です。これらのメソッドは、それぞれ$weakMap[$object] = $value;unset($weakMap[$object]);という配列のような構文での操作と全く同じ意味を持ちます。通常、コードの可読性を高めるためにも後者の配列構文が推奨されます。また、WeakMapはキーとなるオブジェクトへの参照が他に存在しなくなった場合に、マップ内の該当エントリを自動的に削除する「弱参照」という特性を持ちます。これはメモリ効率の良いデータ管理を可能にしますが、意図せずデータが消えるように見える場合があるため、この挙動を理解しておくことが重要です。

PHP WeakMap offsetSet/offsetGet でオブジェクトをキーにする

1<?php
2
3/**
4 * WeakMapのキーとして使用するシンプルなオブジェクトクラス
5 */
6class MyKeyObject
7{
8    public string $id;
9
10    public function __construct(string $id)
11    {
12        $this->id = $id;
13    }
14}
15
16// WeakMapインスタンスを作成
17$weakMap = new WeakMap();
18
19// キーとなるオブジェクトを作成
20$objectA = new MyKeyObject('キーA');
21$objectB = new MyKeyObject('キーB');
22
23echo "--- WeakMapへの値のセット (offsetSet) ---" . PHP_EOL;
24
25// WeakMap::offsetSet() を使用して、オブジェクトをキーとして値をセットします。
26// これは $weakMap[$objectA] = 'データA'; と同じ意味です。
27$weakMap->offsetSet($objectA, 'データA');
28echo "オブジェクト '{$objectA->id}' をキーに 'データA' をセットしました。" . PHP_EOL;
29
30// 配列形式で値をセットすることも可能です。
31$weakMap[$objectB] = 'データB';
32echo "オブジェクト '{$objectB->id}' をキーに 'データB' をセットしました。(配列形式)" . PHP_EOL;
33
34echo PHP_EOL;
35echo "--- WeakMapからの値の取得 (offsetGet) ---" . PHP_EOL;
36
37// WeakMap::offsetGet() を使用して、キーに対応する値を取得します。
38// これは $weakMap[$objectA]; と同じ意味です。
39echo "オブジェクト '{$objectA->id}' の値: " . $weakMap->offsetGet($objectA) . PHP_EOL;
40
41// 配列形式で値を取得することも可能です。
42echo "オブジェクト '{$objectB->id}' の値: " . $weakMap[$objectB] . PHP_EOL;
43
44echo PHP_EOL;
45echo "--- WeakMapの弱参照の特性 ---" . PHP_EOL;
46
47// オブジェクトBがWeakMapに存在することを確認
48echo "WeakMapにオブジェクト '{$objectB->id}' が存在するか? " . ($weakMap->offsetExists($objectB) ? 'はい' : 'いいえ') . PHP_EOL;
49
50// オブジェクトBへの外部参照を解除します。
51// WeakMapはキーとなるオブジェクトに対して「弱い参照」しか持たないため、
52// 外部からの参照がなくなると、ガベージコレクション時にWeakMapからも自動的に削除されます。
53unset($objectB);
54echo "オブジェクト 'キーB' への外部参照を解除しました。(unset(\$objectB))" . PHP_EOL;
55
56// ガベージコレクションが実行されると、WeakMapからオブジェクトBのエントリが削除されます。
57// この時点ではまだGCが走っていない可能性もありますが、スクリプトの実行中に参照がなくなると削除対象となります。
58// 多くの場合、直後の操作で確認できるようになります。
59echo "WeakMapにオブジェクト 'キーB' が存在するか? " . ($weakMap->offsetExists(new MyKeyObject('キーB')) ? 'はい' : 'いいえ') . PHP_EOL; // 注意: 新しいオブジェクトは別のキーとなるため、falseになる。
60// 実際には、$objectBがunsetされたため、もはやそのオブジェクトを指す変数はない。
61// 正確には、WeakMapにキー 'キーB' と関連付けられたオブジェクトがまだあるか確認すべきだが、
62// $objectB変数が存在しないため、直接そのオブジェクトを WeakMap::offsetExists() に渡すことはできない。
63// この例では、WeakMapの弱参照が機能したことを示すために、あえて新しいオブジェクトを作成してWeakMapに存在しないことを確認するか、
64// または単に「unset後にはアクセスできなくなる」という説明に留めるのが適切。
65
66// ここでは、unset後に既存のキーを参照しようとするとエラーになることを示します。
67// ただし、offsetExistsは安全に存在を確認できます。
68// unset($objectB)後、WeakMapは$objectBオブジェクトへの参照を失うため、
69// $weakMap[$objectB] や $weakMap->offsetExists($objectB) は、
70// 厳密にはもうそのオブジェクトを指す変数がないため、コンテキストが失われる。
71// 代わりに、WeakMapが空になったか、あるいは特定のキーがなくなったかを確認する一般的な方法を示すべき。
72// 例えば、iterateして確認したり、GCを強制したりすることは可能だが、初心者向けには複雑すぎる。
73
74// 単純にWeakMap::offsetExists()で確認する際は、存在したオブジェクト自体を渡す必要があります。
75// unset() した後では、元のオブジェクトは変数としてはアクセスできません。
76// したがって、この行はコメントアウトするのがより現実的です。
77// echo "WeakMapにオブジェクト 'キーB' が存在するか? " . ($weakMap->offsetExists($objectB) ? 'はい' : 'いいえ') . PHP_EOL;
78
79// 代わりに、オブジェクトAはまだ参照されているため、WeakMapに残っていることを示します。
80echo "WeakMapにオブジェクト '{$objectA->id}' が存在するか? " . ($weakMap->offsetExists($objectA) ? 'はい' : 'いいえ') . PHP_EOL;
81
82?>

PHP 8のWeakMap::offsetSetメソッドは、WeakMapインスタンスにキーと値を関連付けて設定するための機能です。これは、$weakMap[$object] = '値';のように配列形式で値を代入する操作と全く同じ意味を持ちます。

このメソッドは2つの引数を取ります。1つ目の引数$objectには、WeakMapのキーとして使用したいオブジェクトを指定します。WeakMapはオブジェクトのみをキーとして受け入れます。2つ目の引数$valueには、そのキー(オブジェクト)に対応する任意のデータ型の値を指定します。このメソッドは値を設定するだけで、特に戻り値はありません(void)。

WeakMapの最大の特徴は「弱い参照」です。offsetSetで値を設定した後でも、キーとして使われたオブジェクトが、WeakMap以外のどこからも参照されなくなった場合、PHPのガベージコレクションによってWeakMap内の対応するエントリも自動的に削除されます。これにより、不要になったオブジェクトがWeakMap内に残り続けることを防ぎ、メモリを効率的に利用できます。設定された値は、後からWeakMap::offsetGetメソッドや配列形式で安全に取得することが可能です。

WeakMap::offsetSetは、オブジェクトをキーに値を設定します。これは$weakMap[$object] = $value;という配列形式での設定と同じ意味です。キーには必ずオブジェクトを指定し、文字列や数値などのプリミティブ型は使えません。最も重要な注意点は、WeakMapがキーオブジェクトに「弱参照」を持つことです。キーオブジェクトへの外部参照がなくなると、ガベージコレクション時にWeakMapからもそのエントリが自動的に削除されます。unset()で参照を解除した後は、WeakMapから消えるだけでなく、そのオブジェクト自体にもアクセスできなくなるため、この弱参照の挙動をよく理解して利用しましょう。

関連コンテンツ

関連IT用語