Added Hyperf\Utils\Reflection\ClassInvoker. (#3267)

Added `Hyperf\Utils\Reflection\ClassInvoker` which you can used to execute non public methods or get non public properties.
This commit is contained in:
李铭昕 2021-02-16 11:27:03 +08:00 committed by GitHub
parent 9b04755d89
commit ace7be91b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 151 additions and 0 deletions

View File

@ -3,6 +3,7 @@
## Added ## Added
- [#3261](https://github.com/hyperf/hyperf/pull/3261) Added method `Pipeline::handleCarry()` which to handle the returning value. - [#3261](https://github.com/hyperf/hyperf/pull/3261) Added method `Pipeline::handleCarry()` which to handle the returning value.
- [#3267](https://github.com/hyperf/hyperf/pull/3267) Added `Hyperf\Utils\Reflection\ClassInvoker` which you can used to execute non public methods or get non public properties.
# v2.1.6 - 2021-02-08 # v2.1.6 - 2021-02-08

View File

@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace Hyperf\Utils\Reflection;
use ReflectionClass;
class ClassInvoker
{
/**
* @var object
*/
protected $instance;
/**
* @var ReflectionClass
*/
protected $reflection;
public function __construct(object $instance)
{
$this->instance = $instance;
$this->reflection = new ReflectionClass($instance);
}
public function __get($name)
{
$property = $this->reflection->getProperty($name);
$property->setAccessible(true);
return $property->getValue($this->instance);
}
public function __call($name, $arguments)
{
$method = $this->reflection->getMethod($name);
$method->setAccessible(true);
return $method->invokeArgs($this->instance, $arguments);
}
}

View File

@ -0,0 +1,99 @@
<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace HyperfTest\Utils\Reflection;
use Hyperf\Utils\Reflection\ClassInvoker;
use Mockery;
use PHPUnit\Framework\TestCase;
/**
* @internal
* @coversNothing
*/
class ClassInvokerTest extends TestCase
{
protected function tearDown(): void
{
Mockery::close();
}
public function testClassInvokerCall()
{
$invoker = new ClassInvoker(new Caller());
$this->assertSame(1, $invoker->one());
$this->assertSame(1, $invoker->one());
$this->assertSame(123, $invoker->two(123));
$this->assertSame(3, $invoker->three(1, 2));
}
public function testClassInvokerGet()
{
$invoker = new ClassInvoker(new Caller());
$this->assertSame(null, $invoker->id);
$this->assertSame(md5(''), $invoker->md5);
$this->assertSame(sha1(''), $invoker->sha);
$invoker = new ClassInvoker(new Caller($id = uniqid()));
$this->assertSame($id, $invoker->id);
$this->assertSame(md5($id), $invoker->md5);
$this->assertSame(sha1($id), $invoker->sha);
}
public function testClassInvokerCallNotExistMethod()
{
$invoker = new ClassInvoker(new Caller());
$this->expectException(\ReflectionException::class);
$this->expectExceptionMessage('Method zero does not exist');
$invoker->zero();
}
public function testClassInvokerGetNotExistProperty()
{
$invoker = new ClassInvoker(new Caller());
$this->expectException(\ReflectionException::class);
$this->expectExceptionMessage('Property zero does not exist');
$invoker->zero;
}
}
class Caller
{
public $id;
protected $sha;
private $md5;
public function __construct($id = null)
{
$this->id = $id;
$this->md5 = md5($id ?? '');
$this->sha = sha1($id ?? '');
}
public function three($a, $b)
{
return $a + $b;
}
protected function two($data)
{
return $data;
}
private function one()
{
return 1;
}
}