privateやprotectedなプロパティに値を設定したり、値を取得する場合、ReflectionPropertyクラスを使用します。 同様に、pivateやprotectedのメソッドを実行する場合、ReflectionMethodを使用します。 ユニットテストでこれらを使うと、ユニットテストのためだけにpublicにする必要がなくなります。
参考 ユニットテスト用支援クラスのサンプル
メソッド
ReflectionMethodクラスを使用して、PrivateとProtectedなメソッドを実行する方法。 手順は以下になります。
- ReflectionMethodのインスタンス作成
- setAccessibleメソッドでアクセス許可にする
- invokeメソッドで、publicでないメソッドを実行
参照
サンプルは以下のようになります。
<?php class Calc { private function add($a, $b) { return $a + $b; } protected function max($a, $b) { return $a >= $b ? $a : $b; } } $calc = new Calc(); // private method $method = new ReflectionMethod($calc, 'add'); $method->setAccessible(true); $result = $method->invoke($calc, 3, 4); var_dump($result); // 結果は7 // protected method $method = new ReflectionMethod($calc, 'max'); $method->setAccessible(true); $result = $method->invoke($calc, 3, 4); var_dump($result); // 結果は4PrivateやProtectedの場合、setAccessible(true)が無いと、invokeメソッドの実行箇所でエラーになります。
プロパティ
ReflectionPropertyクラスを使用して、PrivateとProtectedなプロパティの値を取得したり、変更する方法。 手順は以下になります。
- ReflectionPropertyのインスタンス作成
- setAccessibleメソッドでアクセス許可にする
- getValueまたはsetValueメソッドを実行
参照
サンプルは以下のようになります。
<?php class Book { private $title; protected $price; public function __construct($title, $price) { $this->title = $title; $this->price = $price; } public function getTitle() { return $this->title; } public function getPrice() { return $this->price; } } $book = new Book('タイトル', 1080); $propTitle = new ReflectionProperty(get_class($book), 'title'); $propPrice = new ReflectionProperty(get_class($book), 'price'); // アクセス許可を設定 $propTitle->setAccessible(true); $propPrice->setAccessible(true); var_dump($propTitle->getValue($book)); // 実行結果: string(12) "タイトル" var_dump($propPrice->getValue($book)); // 実行結果: int(1080) $propTitle->setValue($book, '修正タイトル'); $propPrice->setValue($book, 2160); var_dump($propTitle->getValue($book)); // 実行結果: string(18) "修正タイトル" var_dump($propPrice->getValue($book)); // 実行結果: int(2160)