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 相关文章推荐
Banner程序
Oct 09 PHP
php控制linux服务器常用功能 关机 重启 开新站点等
Sep 05 PHP
用php简单实现加减乘除计算器
Jan 06 PHP
PHP常用的缓存技术汇总
May 05 PHP
thinkphp模板用法和内容输出实例
Nov 28 PHP
php简单实现无限分类树形列表的方法
Mar 27 PHP
php的crc32函数使用时需要注意的问题(不然就是坑)
Apr 21 PHP
在Laravel框架里实现发送邮件实例(邮箱验证)
May 20 PHP
php实现不通过扩展名准确判断文件类型的方法【finfo_file方法与二进制流】
Apr 18 PHP
php通过各种函数判断0和空
Jul 04 PHP
PHP PDOStatement::closeCursor讲解
Jan 30 PHP
laravel请求参数校验方法
Oct 10 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简单实现文本计数器的方法
2016/04/28 PHP
php each 返回数组中当前的键值对并将数组指针向前移动一步实例
2016/11/22 PHP
javascript 面向对象编程基础 多态
2009/08/21 Javascript
纯JavaScript实现HTML5 Canvas六种特效滤镜示例
2013/06/28 Javascript
javascript抖动元素的小例子
2013/10/28 Javascript
js读写json文件实例代码
2014/10/21 Javascript
js中函数声明与函数表达式
2015/06/03 Javascript
javascript实现网页屏蔽Backspace事件,输入框不屏蔽
2015/07/21 Javascript
JavaScript如何动态创建table表格
2020/08/02 Javascript
JS实现对中文字符串进行utf-8的Base64编码的方法(使其与Java编码相同)
2016/06/21 Javascript
原生javascript实现分页效果
2017/04/21 Javascript
JS常见DOM节点操作示例【创建 ,插入,删除,复制,查找】
2018/05/14 Javascript
解决vue移动端适配问题
2018/12/12 Javascript
VueJs里利用CryptoJs实现加密及解密的方法示例
2019/04/29 Javascript
Vue CLI2升级至Vue CLI3的方法步骤
2019/05/20 Javascript
把项目从Python2.x移植到Python3.x的经验总结
2015/04/20 Python
Python实现合并字典的方法
2015/07/07 Python
jupyter安装小结
2016/03/13 Python
python连接mysql实例分享
2016/10/09 Python
python matplotlib 注释文本箭头简单代码示例
2018/01/08 Python
Python实现的径向基(RBF)神经网络示例
2018/02/06 Python
python 信息同时输出到控制台与文件的实例讲解
2018/05/11 Python
pandas 把数据写入txt文件每行固定写入一定数量的值方法
2018/12/28 Python
详解python中的模块及包导入
2019/08/30 Python
用OpenCV将视频分解成单帧图片,图片合成视频示例
2019/12/10 Python
简单了解为什么python函数后有多个括号
2019/12/19 Python
python Manager 之dict KeyError问题的解决
2019/12/21 Python
Free People中国官网:波西米亚风格女装服饰
2016/08/30 全球购物
到底Java是如何传递参数的?是by value或by reference?
2012/07/13 面试题
物理教育专业毕业生推荐信
2013/11/03 职场文书
专业幼师实习生自我鉴定范文
2013/12/08 职场文书
责任书格式
2015/01/29 职场文书
入党积极分子群众意见
2015/06/01 职场文书
2019行政前台转正申请书范文3篇
2019/08/15 职场文书
vue整合百度地图显示指定地点信息
2022/04/06 Vue.js
让JavaScript代码更加精简的方法技巧
2022/06/01 Javascript