PHP实用小技巧之调用录像的方法


Posted in PHP onDecember 05, 2019

主要功能

把你实际的调用操作录下来,然后在你想要的地方重新调用

和匿名函数的作用基本一样,暂存你的调用操作 一般用于链式调用, 然后实际作用于你想要操作的对象上面

好像和没说一样

使用场景

假如 laravel 项目用到了 仓库模式, 然后对于比较复杂的查询条件,一般情况下有三种操作

  • 针对特殊查询增加方法
  • 定一个规则,按照这个规则组装数组,然后需要在 仓库类 里面实现解析
  • 传匿名函数,匿名函数里面写查询条件

现在可以对第三种方法进行优化,传入一个下面代码里的 CallEcho 对象

//控制器里
$callEcho = (new CallEcho())->where("username", "马云")->where("is_boss", 1)->first();
$fubao = (new UserRepository)->first($callEcho);

//仓库类
class UserRepository{
  public function first(CallEcho $callEcho){
    return $callEcho->invoke(new User());
  }
}

看着和匿名函数差不多,但是 CallEcho 可以被继承来实现些接口,继承后还可以对查询条件进行一些操作,比如过滤什么的。用匿名函数的话,完全就看调用方的良心了。

最重要的是不传对象传函数叫什么面对对象

上代码

class CallEcho
{

  protected $callable = null;

  public function __construct()
  {  
    //callable 初始化
    $this->seed();
  }

  protected function seed(){
    $this->callable = $this;
  }

  public function __invoke($obj)
  {
    return $obj;
  }

  public function __call($name, $arguments)
  {
    $current = $this->callable;
    /**
     * 每产生__call,就往callable上面裹一层
     */
    $this->callable = function($obj) use($name, $arguments, $current){
      return call_user_func_array($current, [$obj])->{$name}(...$arguments);
    };
    return $this;
  }
  
  //作用于真正的对象上面
  public function invoke($obj){
    return call_user_func_array($this->callable, [$obj]);
  }
}

简单的测试 以及 使用

class TestCallEcho{
  protected $called = [];

  public function __call($name, $arguments)
  {
    $this->called[] = [$name, $arguments];
    return $this;
  }

  public function end(){
    $this->called[] = "end";
    return $this;
  }

  public function getCalled(){
    return $this->called;
  }
}

function testArrayEq($array1, $array2){
  if(count($array1) !== count($array2)){
    return false;
  }

  foreach ($array1 as $index => $value1){
    if(!isset($array2[$index])){
      return false;
    }
    $value2 = $array2[$index];

    if(is_array($value1) && is_array($value2)){
      if(!testArrayEq($value1, $value2)){
        return false;
      }else{
        //继续判断
      }
    }else{
      if($value1 !== $value2){
        return false;
      }
    }
  }
  return true;
}

function testTestArrayEq(){
  $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 = new CallEcho();

/*************重点开始****************/
/** @var CallEcho $callEcho */
$callEcho = $callEcho->testNumber(1)->testString("myname")->testObj($obj)->testMulti(1, "myname")->testMulti2("1", $obj)->end();

/** @var TestCallEcho $testCallEcho */
$testCallEcho = $callEcho->invoke(new TestCallEcho());
/************重点结束****************/

//基本上和这个作用一样
$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 中间件 的实现

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
一个可查询所有表的“通用”查询分页类
Oct 09 PHP
通过table标签,PHP输出EXCEL的实现方法
Jul 24 PHP
ThinkPHP模板判断输出Defined标签用法详解
Jun 30 PHP
PHP反射机制用法实例
Aug 28 PHP
PHP的数组中提高元素查找与元素去重的效率的技巧解析
Mar 03 PHP
PHP中addslashes与mysql_escape_string的区别分析
Apr 25 PHP
thinkPHP交易详情查询功能详解
Dec 02 PHP
php微信公众平台开发(一) 配置接口
Dec 06 PHP
基于win2003虚拟机中apache服务器的访问
Aug 01 PHP
实例分析基于PHP微信网页获取用户信息
Nov 24 PHP
PHP使用PDO抽象层获取查询结果的方法示例
May 10 PHP
PHP精确到毫秒秒杀倒计时实例详解
Mar 14 PHP
Laravel框架控制器,视图及模型操作图文详解
Dec 04 #PHP
Laravel框架下载,安装及路由操作图文详解
Dec 04 #PHP
Laravel框架Eloquent ORM简介、模型建立及查询数据操作详解
Dec 04 #PHP
PHP实现二维数组(或多维数组)转换成一维数组的常见方法总结
Dec 04 #PHP
PHP实现提取多维数组指定一列的方法总结
Dec 04 #PHP
php实现快速对二维数组某一列进行组装的方法小结
Dec 04 #PHP
PHP实现发送微博消息功能完整示例
Dec 04 #PHP
You might like
PHP+jQuery实现自动补全功能源码
2013/05/15 PHP
删除PHP数组中头部、尾部、任意元素的实现代码
2017/04/10 PHP
ThinkPHP实现转换数据库查询结果数据到对应类型的方法
2017/11/16 PHP
Laravel框架自定义验证过程实例分析
2019/02/01 PHP
js实现DIV的一些简单控制
2007/06/04 Javascript
csdn 博客的css样式 v3
2009/02/24 Javascript
jQuery 技巧大全(新手入门篇)
2009/05/12 Javascript
javascript开发随笔二 动态加载js和文件
2011/11/25 Javascript
关于 文本框默认值 的操作js代码
2012/01/12 Javascript
使用jquery hover事件实现表格的隔行换色功能示例
2013/09/03 Javascript
JavaScript数据类型之基本类型和引用类型的值
2015/04/01 Javascript
使用jquery获取url及url参数的简单实例
2016/06/14 Javascript
教你一步步用jQyery实现轮播器
2016/12/18 Javascript
详解jQuery中的easyui
2018/09/02 jQuery
vue axios数据请求get、post方法及实例详解
2018/09/11 Javascript
详解如何使用webpack打包多页jquery项目
2019/02/01 jQuery
使用jQuery mobile NuGet让你的网站在移动设备上同样精彩
2019/06/18 jQuery
Vue中el-form标签中的自定义el-select下拉框标签功能
2020/04/20 Javascript
解决vant中 tab栏遇到的坑 van-tabs
2020/11/04 Javascript
Python中itertools模块用法详解
2014/09/25 Python
听歌识曲--用python实现一个音乐检索器的功能
2016/11/15 Python
python中验证码连通域分割的方法详解
2018/06/04 Python
python中的decorator的作用详解
2018/07/26 Python
浅述python2与python3的简单区别
2018/09/19 Python
在python2.7中用numpy.reshape 对图像进行切割的方法
2018/12/05 Python
Python中正则表达式的用法总结
2019/02/22 Python
用django设置session过期时间的方法解析
2019/08/05 Python
Django serializer优化类视图的实现示例
2020/07/16 Python
前端使用canvas生成盲水印的加密解密的实现
2020/12/16 HTML / CSS
法国春天百货官网:Printemps.com
2020/06/29 全球购物
大学老师推荐信
2014/02/25 职场文书
房产代理公证处委托书
2014/04/04 职场文书
房屋买卖委托书格式范本格式
2014/10/13 职场文书
感谢信范文大全
2015/01/23 职场文书
义卖募捐活动总结
2015/05/09 职场文书
2015年乡镇安全生产工作总结
2015/05/19 职场文书