php的猴子补丁,动态改变函数和类方法,需要runkit扩展

2019-12-04  本文已影响0人  sorry510

安装

php5版本扩展下载地址https://pecl.php.net/package/runkit/1.0.4/windows
php7版本下载地址https://pecl.php.net/package/runkit7/3.0.0/windows因为原作者不开发了,被别人已接手

使用方法例子

// 动态修改函数
function test() {
   echo "php";
}

runkit7_function_redefine('test', function($a) {
     echo $a . ' python';
});
test('hello'); // hello python

// 动态修改类的方法
class A {
    public function test() {
        return 'php';
    }
}

runkit7_method_redefine(
    'A',
    'test',
    function ($name = 'hello') {
        return $name . ' python';
    },
    RUNKIT7_ACC_PUBLIC
);

echo (new A())->test(); // hello python

详细文档

https://www.php.net/manual/zh/book.runkit.php
php7需要将runkit_*替换为runkit7_*

runkit7的github地址

https://github.com/runkit7/runkit7

简单封装

构造函数必须接受一个实例类(只有让composer自动加载了这个类文件,才能改变这个类的方法)

class MonkeyPatch
{
  public function __construct($class)
  {
    if (!function_exists('runkit7_method_redefine')) {
      die('runkit extends not find');
    }
    $this->className = get_class($class);
  }

  public function changeMethod($method, Closure $callback, $type = \RUNKIT7_ACC_PUBLIC)
  {
    return runkit7_method_redefine(
      $this->className,
      $method,
      $callback,
      $type
    );
  }
}

// use
$patch = new MonkeyPatch(new A);
$result = $patch->changeMethod('test', function ($name = 'hello') {
        return $name . ' java';
});
上一篇下一篇

猜你喜欢

热点阅读