mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-12-02 03:37:44 +08:00
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:
parent
9b04755d89
commit
ace7be91b1
@ -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
|
||||||
|
|
||||||
|
51
src/utils/src/Reflection/ClassInvoker.php
Normal file
51
src/utils/src/Reflection/ClassInvoker.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
99
src/utils/tests/Reflection/ClassInvokerTest.php
Normal file
99
src/utils/tests/Reflection/ClassInvokerTest.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user