承接 alpa/tools_sucker 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

alpa/tools_sucker

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

alpa/tools_sucker 适用场景与选型建议

alpa/tools_sucker 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 12 次下载、GitHub Stars 达 1, 最近一次更新时间为 2023 年 02 月 17 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 alpa/tools_sucker 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 alpa/tools_sucker 我们能提供哪些服务?
定制开发 / 二次开发

基于 alpa/tools_sucker 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 12
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 5
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2023-02-17