1
1

More than 5 years have passed since last update.

runkitでprivateな__constructを呼び出す

Posted at

前回の続き。
runkitにはクラスに対しても色々やっちゃうことが可能です。

<?php
    // クラス
    class A{ public static function getName(){print('A');} }
    class B{ public static function getName(){print('B');} }
    class C extends A{}
    print(C::getName()); // A

    runkit_constant_add('C::hoge', 1);
    print(C::hoge); // 1

    runkit_class_emancipate('C');
    print(C::getName()); // Fatal error: Call to undefined method C::getName()

    runkit_class_adopt('C', 'B');
    print(C::getName()); // B

クラス定数やメソッドの追加削除に留まらず、親クラス入れ替えなんて芸当もできてしまいます。
ここでは前やったprivateな__construct()呼び出しを、runkitを使ってやってみます。

<?php
    class HOGE{
        public $value = 0;
        private function __construct(){
            $this->value = 1;
        }
    }

    runkit_method_rename('HOGE', '__construct', 'construct');
    runkit_method_add('HOGE', '__construct', '', '$this->construct();', RUNKIT_ACC_PUBLIC);
    $hoge = new HOGE();
    print $hoge->value; // 1

クラスを書き換えた結果、最終的にはこういう形になっていると思われます。

<?php
    class HOGE{
        public $value = 0;
        public function __construct(){
            $this->construct();
        }
        private function construct(){
            $this->value = 1;
        }
    }

これならごく自然にnewできますね。
いいのかそれ。
なお、最近のPHP関数は引数にクロージャを受け付けてくれるものが多いですが、runkit_method_add()等は文字列しか駄目なようです。

runkitはあまりに強力すぎるため、実環境で使うことはまず無いでしょう。
こんな風に遊んでみるくらいならともかく、仕事でこんなことをやられたらたまったものではありません。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1