private property・method を読み書き・実行
諸事情によりクラスのprivateなproperty、Methodを触る必要がありました。
その時のメモです。
ReflectionClass
ReflectionClass
ReflectionClass を使用することで指定されたクラスのことを調べることが可能です。
サンプルコード
まず実験するための SampleClass
を作成します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| <?php
class SampleClass
{
/**
* @var string プライベートプロパティ
*/
private $text = 'text';
/**
* プライベート変数を出力
*/
public function textOutput()
{
echo $this->text.PHP_EOL;
}
/**
* !で囲う
* @param @string $str 文字列
* @return string
*/
private function output(string $str):string
{
return "!{$str}!";
}
/**
* num1とnum2を足す
* @param int num1 足す数値
* @param int num2 足す数値
* @return int
*/
private function sum(int $num1, int $num2):int
{
return $num1+$num2;
}
}
|
通常アクセスした場合
private property
1
2
| $sample = new SampleClass();
echo $sample->text;
|
実行結果
1
| PHP Fatal error: Uncaught Error: Cannot access private property SampleClass::$text
|
private method
1
2
3
| <?php
$sample = new SampleClass();
echo $sample->output('Hello,World');
|
↓実行結果
PHP Fatal error: Uncaught Error: Call to private method SampleClass::output() from context
ReflectionClassを使用
実際に ReflectionClass を使用してprivateなproperty、Methodに読み書き、使用してみる。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
| <?php
$sample = new SampleClass();
$refrection = new ReflectionClass(get_class($sample));
// プライベートプロパティ text の内容を出力
echo 'Private Property Before--------------------'.PHP_EOL;
$sample->textOutput();
// ------プロパティの読み書き------
// 該当のプロパティを取得
$privateText = $refrection->getProperty('text');
// アクセス権限の取得
$privateText->setAccessible(true);
// 書き込み
$privateText->setValue($sample, "Change Text");
echo PHP_EOL.'Private Property After----------------------'.PHP_EOL;
// 読み込み
echo $privateText->getValue($sample).PHP_EOL;
// プライベートプロパティ text の内容を出力
$sample->textOutput();
echo PHP_EOL.'Private Method------------------------------'.PHP_EOL;
// ------メソッドの実行------
// 該当の関数を取得
$output = $refrection->getMethod('output');
// アクセス権限の取得
$output->setAccessible(true);
// 確認実行
echo $output->invoke($sample, 'Hello,World').PHP_EOL;
// 該当の関数を取得
$sum = $refrection->getMethod('sum');
// アクセス権限の取得
$sum->setAccessible(true);
// 確認実行 変数が複数の時
echo $sum->invoke($sample, 1, 2).PHP_EOL;
|
実行結果
1
2
3
4
5
6
7
8
9
10
| Private Property Before--------------------
text
Private Property After----------------------
Change Text
Change Text
Private Method------------------------------
!Hello,World!
3
|
注意
本来 private になどにされて外部からアクセス出来ないようにされているのは何らかの理由があります。
これはそれを捻じ曲げて行う行為ですので注意してください。
本当にそこをいじるべきなのか、いじったらどんな影響があるかを考えてみてから使用したほうが良いです。
僕は本当にどうしようもなかったので使わざるを得なかったです。