alpa/tools_sucker
最新稳定版本:v1.0.0-alpha
Composer 安装命令:
composer require alpa/tools_sucker
包简介
For unit testing. The sucker for classes and objects to call private methods.
README 文档
README
For unit testing. The sucker for classes and objects to call private methods.
The component provides access to private properties of an object / class.
Install
composer require alpa/tools_sucker:1.0.*
Preface
Let's create classes for examples.
<?php class A{ private $private_prop='hello'; private static $static_private_prop='hello'; private function private_method($arg) { return $arg; } private function & private_methodByReference(&$arg=null) { return $arg; } } class B extends A{ private $private_prop='bay'; private static $static_private_prop='bay'; private function private_method($arg) { return strtoupper($arg); } }
syntactic sugar
There are 3 ways (API) to use the component.
1 way - if you need efficiency and a minimum of executable code under the hood.
use A; use B; use Alpa\Tools\Sucker\SuckerObjectHandlers; use Alpa\Tools\Sucker\SuckerClassHandlers; $handler=new SuckerObjectHandlers(new B); //scope B class echo $handler->get('private_prop');// bay echo "\n"; // scope A class; echo $handler->setScope(A::class)->get('private_prop');// hello echo "\n"; $handler->setScope(null);// reset scope $staticHandlers=new SuckerClassHandlers(B::class); echo $staticHandlers->get('static_private_prop');// hello echo "\n"; echo $handler->setScope(A::class)->get('static_private_prop');// hello echo "\n"; // environment maintained at A class level echo $handler->get('static_private_prop');// hello $handler->setScope(null); // reset scope
2 way - Wrapper pattern. Improves the previous solution.
use A; use B; use Alpa\Tools\Sucker\Sucker; $sucker=new Sucker(new B); echo $sucker->get('private_prop');// bay echo "\n"; echo $sucker(A::class)->get('private_prop');// hello echo "\n"; // Warn : The Scope is automatically reset after calling methods that are responsible for accessing members of the observable object echo $sucker->get('private_prop');// bay echo "\n"; $sucker=new Sucker(B::class); echo $sucker->get('static_private_prop');// bay echo "\n"; echo $sucker(A::class)->get('static_private_prop');// hello echo "\n"; // Warn : The Scope is automatically reset after calling methods that are responsible for accessing members of the observable object echo $sucker->get('static_private_prop');// bay echo "\n";
3 way - Proxy. syntactic sugar.
use A; use B; use Alpa\Tools\Sucker\Proxy; $proxy=new Proxy(new B); echo $proxy->private_prop;// bay echo $proxy(A::class)->private_prop;// hello // Warn : The Scope is automatically reset after calling methods that are responsible for accessing members of the observable object echo $proxy->private_prop;// bay $proxy=new Proxy(B::class); echo $proxy->static_private_prop;// bay echo $proxy(A::class)->static_private_prop;// hello // Warn : The Scope is automatically reset after calling methods that are responsible for accessing members of the observable object echo $proxy->static_private_prop;// bay
Basic principle
The code implements the following principle:
<?php Class A { private $prop='hello'; } $call=function(){ // var_dump($this);//$target // var_dump(self::class);//$slaveClass return $this->prop; }; $target= new A(); $slaveClass=A::class; $call=$call->bindTo($target,$slaveClass); echo $call();
Get value properties
<?php use Alpa\Tools\Sucker\SuckerObjectHandlers; use Alpa\Tools\Sucker\Sucker; use Alpa\Tools\Sucker\Proxy; $handler=new SuckerObjectHandlers(new B); echo $handler->get('private_prop');// bay echo $handler->setScope(A::class)->get('private_prop');// hello //get by reference $var = & $handler->get('private_prop');// & return A::$private_prop ==='hello' $handler->setScope(null); //or $sucker=new Sucker(new B); echo $sucker->get('private_prop');// bay echo $sucker(A::class)->get('private_prop');// hello //get by reference $var = & $sucker(A::class)->get('private_prop');// & return A::$private_prop ==='hello' //or $proxy=new Proxy(new B); echo $proxy->private_prop;// bay echo $proxy(A::class)->private_prop;// hello //get by reference $var = & $proxy(A::class)->private_prop;// & return A::$private_prop ==='hello'
Set value to properties.
<?php use Alpa\Tools\Sucker\SuckerObjectHandlers; use Alpa\Tools\Sucker\Sucker; use Alpa\Tools\Sucker\Proxy; $handler=new SuckerObjectHandlers(new B); //the value is passed by reference. Therefore it is necessary to pass it through a variable $var='BAY'; // set by reference $handler->set('private_prop',$var); //B::$private_prop=$var=>'BAY'; $handler->setScope(A::class)->set('private_prop',$var); //A::$private_prop=$var=>'BAY'; $handler->setScope(null); //or $sucker=new Sucker(new B); $sucker->set('private_prop','HELLO');//B::$private_prop=$var=>'HELLO'; $sucker(A::class)->set('private_prop','HELLO');// //A::$private_prop=$var=>'HELLO'; //get by reference $var='HELLO'; $sucker(A::class)->setRef('private_prop',$var);// A::$private_prop = &$var=>'HELLO' //or $proxy=new Proxy(new B); $proxy->private_prop='HELLO';// B::$private_prop='HELLO' $proxy(A::class)->private_prop='HELLO';// A::$private_prop='HELLO' //With a proxy, transmission by reference is not possible
Check (isset) property
use Alpa\Tools\Sucker\SuckerObjectHandlers; use Alpa\Tools\Sucker\Sucker; use Alpa\Tools\Sucker\Proxy; $handler=new SuckerObjectHandlers(new B); echo $handler->isset('private_prop'); //check $obj(B)::$private_prop; echo $handler->setScope(A::class)->isset('private_prop'); //check $obj(A)::$private_prop; $handler->setScope(null); //or $sucker=new Sucker(new B); $sucker->isset('private_prop');//check $obj(B)::$private_prop $sucker(A::class)->isset('private_prop');// check $obj(A)::$private_prop //or $proxy=new Proxy(new B); echo isset($proxy->private_prop);// check $obj(B)::$private_prop echo isset($proxy(A::class)->private_prop);// $obj(A)::$private_prop
Unset property
use Alpa\Tools\Sucker\SuckerObjectHandlers; use Alpa\Tools\Sucker\Sucker; use Alpa\Tools\Sucker\Proxy; $handler=new SuckerObjectHandlers(new B); $handler->unset('private_prop'); //unset $obj(B)::$private_prop; $handler->setScope(A::class)->unset('private_prop'); //unset $obj(A)::$private_prop; $handler->setScope(null); //or $sucker=new Sucker(new B); $sucker->unset('private_prop');//check $obj(B)::$private_prop $sucker(A::class)->unset('private_prop');// check $obj(A)::$private_prop //or $proxy=new Proxy(new B); unset($proxy->private_prop);// check $obj(B)::$private_prop unset($proxy(A::class)->private_prop);// $obj(A)::$private_prop
Iterate properties
use Alpa\Tools\Sucker\SuckerObjectHandlers; use Alpa\Tools\Sucker\Sucker; use Alpa\Tools\Sucker\Proxy; $handler=new SuckerObjectHandlers(new B); $handler->each(function($key, &$value){ // $value variable passed by reference echo self::class===B::class; // $this =>object B return true; // break }); //unset $obj(B)::$private_prop; $handler->setScope(A::class)->each(function ($key,$value){ echo self::class===A::class; return true; // break }); $handler->setScope(null); //or $sucker=new Sucker(new B); $sucker->each(function($key, &$value){ // $value variable passed by reference echo self::class===B::class; // $this =>object B return true; // break }); $sucker(A::class)->each(function ($key,$value){ echo self::class===A::class; return true; // break }); //or $proxy=new Proxy(new B); foreach($proxy as $key => $value){ // your code } foreach($proxy(A::class) as $key => $value){ // your code }
Call methods
<?php use Alpa\Tools\Sucker\SuckerObjectHandlers; use Alpa\Tools\Sucker\Sucker; use Alpa\Tools\Sucker\Proxy; $handler=new SuckerObjectHandlers(new B); $arg='hello'; // passing a variable by reference $var = $handler->call('private_method',$arg);// HELLO $var = $handler->setScope(A::class)->call('private_method',$arg);// hello // return by reference $var = & $handler->call('private_methodByReference',$arg);// $var = &$arg variables are linked by reference $handler->setScope(null); unset($var,$arg); //or $sucker=new Sucker(new B); $arg='hello'; $var = $sucker->call('private_method','hello');// HELLO $var = $sucker(A::class)->call('private_method','hello');// hello //return by reference $var = & $sucker(A::class)->call('private_method','hello');// hello // arguments by reference $var = & $sucker(A::class)->apply('private_methodByReference',[&$arg]); // $var = &$arg variables are linked by reference unset($var,$arg); //or $proxy=new Proxy(new B); $var = $proxy->private_method('hello');// HELLO $var = $proxy(A::class)->private_method('hello');// hello //return by reference $var = & $proxy(A::class)->private_method('hello');
Sandbox
<?php use Alpa\Tools\Sucker\SuckerObjectHandlers; use Alpa\Tools\Sucker\Sucker; use Alpa\Tools\Sucker\Proxy; $handler=new SuckerObjectHandlers(new B); $arg='hello'; // passing a variable by reference $var = $handler->sandbox(function($arg){ echo self::class===B::class; // $this - object B return $arg; },[$arg]);// hello $var = $handler->setScope(A::class)->sandbox(function($arg){ echo self::class===A::class; // $this - object A return $arg; },[$arg]);// hello //references $var = & $handler->sandbox(function & (&$arg){ return $arg; },[&$arg]);// $var = &$arg variables are linked by reference $handler->setScope(null); unset($var,$arg); //or $sucker=new Sucker(new B); $arg='hello'; $var = $sucker->sandbox(function($arg){ echo self::class===B::class; // $this - object B return $arg; },[$arg]); $var = $sucker(A::class)->setScope(A::class)->sandbox(function($arg){ echo self::class===A::class; // $this - object A return $arg; },[$arg]); // references $var = & $sucker(A::class)->sandbox(function & (&$arg){ return $arg; },[&$arg]); // $var = &$arg variables are linked by reference unset($var,$arg); //or $proxy=new Proxy(new B); $arg='hello'; $var = $proxy(function($arg){ echo self::class===B::class; // $this - object B return $arg; },[$arg]);// hello $var = $proxy(A::class)(function($arg){ echo self::class===A::class; // $this - object A return $arg; },[$arg]);// hello //references $var = & $proxy(function & (&$arg){ return $arg; }); // $var = &$arg variables are linked by reference
统计信息
- 总下载量: 12
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 2
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2023-02-17