🥞

【PHP】クラスの private property・method に読み書き・実行する方法

2020/11/05に公開

概要

諸事情によりクラスのprivateなproperty、Methodを触る必要がありました。
その時のメモです。

ReflectionClass

ReflectionClass
ReflectionClass を使用することで指定されたクラスのことを調べることが可能です。

サンプルコード

実際に ReflectionClass を使用してprivateなproperty、Methodに読み書き、使用してみる。

<?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;
    }
}
 
$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;

↓実行結果

Private Property Before--------------------
text

Private Property After----------------------
Change Text
Change Text

Private Method------------------------------
!Hello,World!
3

通常アクセスした場合

private property

echo $sample->text;

↓実行結果

PHP Fatal error:  Uncaught Error: Cannot access private property SampleClass::$text

private method

echo $sample->output('Hello,World');

↓実行結果

PHP Fatal error:  Uncaught Error: Call to private method SampleClass::output() from context

注意

本来 private になどにされて外部からアクセス出来ないようにされているのは何らかの理由があります。
これはそれを捻じ曲げて行う行為ですので注意してください。
本当にそこをいじるべきなのか、いじったらどんな影響があるかを考えてみてから使用したほうが良いです。

僕は本当にどうしようもなかったので使わざるを得なかったです。

Discussion