PHP实用小技巧之调用录像的方法
主要功能
把你实际的调用操作录下来,然后在你想要的地方重新调用
和匿名函数的作用基本一样,暂存你的调用操作一般用于链式调用,然后实际作用于你想要操作的对象上面
好像和没说一样
使用场景
假如laravel项目用到了仓库模式,然后对于比较复杂的查询条件,一般情况下有三种操作
- 针对特殊查询增加方法
- 定一个规则,按照这个规则组装数组,然后需要在仓库类里面实现解析
- 传匿名函数,匿名函数里面写查询条件
现在可以对第三种方法进行优化,传入一个下面代码里的CallEcho对象
//控制器里
$callEcho=(newCallEcho())->where("username","马云")->where("is_boss",1)->first();
$fubao=(newUserRepository)->first($callEcho);
//仓库类
classUserRepository{
publicfunctionfirst(CallEcho$callEcho){
return$callEcho->invoke(newUser());
}
}
看着和匿名函数差不多,但是CallEcho可以被继承来实现些接口,继承后还可以对查询条件进行一些操作,比如过滤什么的。用匿名函数的话,完全就看调用方的良心了。
最重要的是不传对象传函数叫什么面对对象
上代码
classCallEcho
{
protected$callable=null;
publicfunction__construct()
{
//callable初始化
$this->seed();
}
protectedfunctionseed(){
$this->callable=$this;
}
publicfunction__invoke($obj)
{
return$obj;
}
publicfunction__call($name,$arguments)
{
$current=$this->callable;
/**
*每产生__call,就往callable上面裹一层
*/
$this->callable=function($obj)use($name,$arguments,$current){
returncall_user_func_array($current,[$obj])->{$name}(...$arguments);
};
return$this;
}
//作用于真正的对象上面
publicfunctioninvoke($obj){
returncall_user_func_array($this->callable,[$obj]);
}
}
简单的测试以及使用
classTestCallEcho{
protected$called=[];
publicfunction__call($name,$arguments)
{
$this->called[]=[$name,$arguments];
return$this;
}
publicfunctionend(){
$this->called[]="end";
return$this;
}
publicfunctiongetCalled(){
return$this->called;
}
}
functiontestArrayEq($array1,$array2){
if(count($array1)!==count($array2)){
returnfalse;
}
foreach($array1as$index=>$value1){
if(!isset($array2[$index])){
returnfalse;
}
$value2=$array2[$index];
if(is_array($value1)&&is_array($value2)){
if(!testArrayEq($value1,$value2)){
returnfalse;
}else{
//继续判断
}
}else{
if($value1!==$value2){
returnfalse;
}
}
}
returntrue;
}
functiontestTestArrayEq(){
$array1=[1,2];
$array2=[1,3];
$array3=[1,2,3];
assert(testArrayEq($array1,$array2)==false);
assert(testArrayEq($array1,$array3)==false);
assert(testArrayEq($array1,$array1)==true);
}
testTestArrayEq();
$obj=new\stdClass();
$callEcho=newCallEcho();
/*************重点开始****************/
/**@varCallEcho$callEcho*/
$callEcho=$callEcho->testNumber(1)->testString("myname")->testObj($obj)->testMulti(1,"myname")->testMulti2("1",$obj)->end();
/**@varTestCallEcho$testCallEcho*/
$testCallEcho=$callEcho->invoke(newTestCallEcho());
/************重点结束****************/
//基本上和这个作用一样
$a=function($obj){
$obj->testNumber(1)->testString("myname")->testObj($obj)->testMulti(1,"myname")->testMulti2("1",$obj)->end();
};
$called=$testCallEcho->getCalled();
$eq=testArrayEq($called,[
["testNumber",[1]],
["testString",["myname"]],
["testObj",[$obj]],
["testMulti",[1,"myname"]],
["testMulti2",["1",$obj]],
"end"
]);
assert($eq);
PS
灵感来源于slim3中间件的实现
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。