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 相关文章推荐
高亮度显示php源代码
Oct 09 PHP
使用adodb lite解决问题
Dec 31 PHP
PHP下打开URL地址的几种方法小结
May 16 PHP
实用PHP会员权限控制实现原理分析
May 29 PHP
PHP中的错误处理、异常处理机制分析
May 07 PHP
PHP关联数组的10个操作技巧
Jan 21 PHP
php多个字符串替换成同一个的解决方法
Jun 18 PHP
is_uploaded_file函数引发的不能上传文件问题
Oct 29 PHP
PHP将进程作为守护进程的方法
Mar 19 PHP
php实现数组按指定KEY排序的方法
Mar 30 PHP
Yii2 批量插入、更新数据实例
Mar 15 PHP
php菜单/评论数据递归分级算法的实现方法
Aug 01 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
用ADODB来让PHP操作ACCESS数据库的方法
2006/12/31 PHP
php的curl实现get和post的代码
2008/08/23 PHP
php中使用$_REQUEST需要注意的一个问题
2013/05/02 PHP
js以对象为索引的关联数组
2010/07/04 Javascript
(function($){...})(jQuery)的意思
2010/07/22 Javascript
jQuery事件绑定.on()简要概述及应用
2013/02/07 Javascript
JavaScript使用Replace进行字符串替换的方法
2015/04/14 Javascript
javascript处理a标签超链接默认事件的方法
2015/06/29 Javascript
什么是JavaScript注入攻击?
2016/09/14 Javascript
jQuery插件HighCharts绘制2D饼图效果示例【附demo源码下载】
2017/03/21 jQuery
vue 2.0组件与v-model详解
2017/03/27 Javascript
信息滚动效果的实例讲解
2017/09/18 Javascript
移动端网页开发调试神器Eruda的介绍与使用技巧
2017/10/30 Javascript
react中fetch之cors跨域请求的实现方法
2018/03/14 Javascript
Node.js如何对SQLite的async/await封装详解
2019/02/14 Javascript
[00:17]游戏风云独家报道:DD赛后说出数字秘密 吓死你们啊!
2014/07/13 DOTA
Python文件右键找不到IDLE打开项解决办法
2015/06/08 Python
快速实现基于Python的微信聊天机器人示例代码
2017/03/03 Python
Python 字符串与二进制串的相互转换示例
2018/07/23 Python
Python生态圈图像格式转换问题(推荐)
2019/12/02 Python
opencv3/C++图像像素操作详解
2019/12/10 Python
python 下载文件的多种方法汇总
2020/11/17 Python
CSS3弹性盒模型开发笔记(二)
2016/04/26 HTML / CSS
英国电动工具购买网站:Anglia Tool Centre
2017/04/25 全球购物
Tretorn美国官网:瑞典外套和鞋类品牌,抵御风雨
2018/07/19 全球购物
zooplus意大利:在线宠物商店
2019/08/07 全球购物
银行会计职员个人的自我评价
2013/09/29 职场文书
小学生期末自我鉴定
2014/01/19 职场文书
本科应届生自荐信
2014/06/29 职场文书
2014年宣传部工作总结
2014/11/12 职场文书
实习工作表现评语
2014/12/31 职场文书
2015年幼儿园班主任工作总结
2015/05/12 职场文书
辩论赛新闻稿
2015/07/17 职场文书
先进教师个人主要事迹材料
2015/11/03 职场文书
导游词之徐州云龙湖
2019/11/19 职场文书
Canvas三种动态画圆实现方法说明(小结)
2021/04/16 Javascript