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
PHP 进程锁定问题分析研究
Nov 24 PHP
收藏的PHP常用函数 推荐收藏保存
Feb 21 PHP
PHP 5.3新特性命名空间规则解析及高级功能
Mar 11 PHP
PHP语言中global和$GLOBALS[]的分析 之二
Feb 02 PHP
改写ThinkPHP的U方法使其路由下分页正常
Jul 02 PHP
php实现在服务器端调整图片大小的方法
Jun 16 PHP
Joomla开启SEF的方法
May 04 PHP
thinkphp实现分页显示功能
Dec 03 PHP
Yii全局函数用法示例
Jan 22 PHP
PHP实现针对日期,月数,天数,周数,小时,分,秒等的加减运算示例【基于strtotime】
Apr 19 PHP
在Laravel中实现使用AJAX动态刷新部分页面
Oct 15 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
福利彩票幸运号码自动生成器
2006/10/09 PHP
php完全过滤HTML,JS,CSS等标签
2009/01/16 PHP
用mysql内存表来代替php session的类
2009/02/01 PHP
PHP三元运算的2种写法代码实例
2014/05/12 PHP
Mootools 1.2教程 同时进行多个形变动画
2009/09/15 Javascript
如何阻止复制剪切和粘贴事件为了表单内容的安全
2013/05/23 Javascript
让人蛋疼的JavaScript语法特性
2014/09/30 Javascript
使用原生JS实现弹出层特效
2014/12/22 Javascript
JavaScript中的console.assert()函数介绍
2014/12/29 Javascript
详解JavaScript中jQuery和Ajax以及JSONP的联合使用
2015/08/13 Javascript
jquery自定义表格样式
2015/11/23 Javascript
RequireJS多页面应用实例分析
2016/06/29 Javascript
vue组件父子间通信详解(三)
2017/11/07 Javascript
tween.js缓动补间动画算法示例
2018/02/13 Javascript
node的process以及child_process模块学习笔记
2018/03/06 Javascript
vue 中 beforeRouteEnter 死循环的问题
2019/04/23 Javascript
Node中对非阻塞I/O、事件循环的知识点总结
2020/01/05 Javascript
实例讲解React 组件生命周期
2020/07/08 Javascript
0基础学习前端开发的一些建议
2020/07/14 Javascript
如何在Python中编写并发程序
2016/02/27 Python
Django ManyToManyField 跨越中间表查询的方法
2018/12/18 Python
说说如何遍历Python列表的方法示例
2019/02/11 Python
解决Python内层for循环如何break出外层的循环的问题
2019/06/24 Python
基于Python+Appium实现京东双十一自动领金币功能
2019/10/31 Python
浅谈Pycharm最有必要改的几个默认设置项
2020/02/14 Python
Django-silk性能测试工具安装及使用解析
2020/11/28 Python
如何在vscode中安装python库的方法步骤
2021/01/06 Python
Feelunique德国官方网站:欧洲最大的在线美容零售商
2019/07/20 全球购物
最新远光软件笔试题面试题内容
2013/11/08 面试题
民族团结先进集体事迹材料
2014/05/22 职场文书
我爱幼儿园演讲稿
2014/09/11 职场文书
党的群众路线对照检查材料思想汇报
2014/09/25 职场文书
七年级上册语文教学计划
2015/01/22 职场文书
幼儿园新生开学寄语
2015/05/27 职场文书
高温慰问简报
2015/07/21 职场文书
nginx内存池源码解析
2021/11/20 Servers