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 discuz 主题表和回帖表的设计
Mar 13 PHP
php上传文件的增强函数
Jul 21 PHP
php实现mysql封装类示例
May 07 PHP
Laravel框架路由配置总结、设置技巧大全
Sep 03 PHP
PHP实现绘制3D扇形统计图及图片缩放实例
Oct 01 PHP
Thinkphp中数据按分类嵌套循环实现方法
Oct 30 PHP
PHP Header用于页面跳转时的几个注意事项
Oct 21 PHP
php获取ip及网址的简单方法(必看)
Apr 01 PHP
小程序微信退款功能实现方法详解【基于thinkPHP】
May 05 PHP
php设计模式之状态模式实例分析【星际争霸游戏案例】
Mar 26 PHP
Yii实现微信公众号场景二维码的方法实例
Aug 30 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解答方法
2012/02/04 PHP
php查看网页源代码的方法
2015/03/13 PHP
php操作MongoDB类实例
2015/06/17 PHP
php获取微信基础接口凭证Access_token
2018/08/23 PHP
JavaScript(js)设置默认输入焦点(focus)
2012/12/28 Javascript
关于IE中getElementsByClassName不能用的问题解决方法
2013/08/26 Javascript
js完美解决IE6不支持position:fixed的bug
2015/04/24 Javascript
如何用javascript计算文本框还能输入多少个字符
2015/07/29 Javascript
js中unicode转码方法详解
2015/10/09 Javascript
Bootstrap modal 多弹窗之叠加关闭阴影遮罩问题的解决方法
2017/02/27 Javascript
基于Bootstrap table组件实现多层表头的实例代码
2017/09/07 Javascript
Node调用Java的示例代码
2017/09/20 Javascript
性能优化篇之Webpack构建速度优化的建议
2019/04/03 Javascript
nodejs实现获取本地文件夹下图片信息功能示例
2019/06/22 NodeJs
vue实现简单的日历效果
2020/09/24 Javascript
Nuxt使用Vuex的方法示例
2019/09/06 Javascript
vue+springboot图片上传和显示的示例代码
2020/02/14 Javascript
[43:47]完美世界DOTA2联赛PWL S3 LBZS vs Phoenix 第一场 12.09
2020/12/11 DOTA
c++生成dll使用python调用dll的方法
2014/01/20 Python
Python Web程序部署到Ubuntu服务器上的方法
2018/02/22 Python
python自动化报告的输出用例详解
2018/05/30 Python
python实现dijkstra最短路由算法
2019/01/17 Python
在Python中过滤Windows文件名中的非法字符方法
2019/06/10 Python
从训练好的tensorflow模型中打印训练变量实例
2020/01/20 Python
java字符串格式化输出实例讲解
2021/01/06 Python
CSS3 clip-path 用法介绍详解
2018/03/01 HTML / CSS
CSS3 实现footer 固定在底部(无论页面多高始终在底部)
2019/10/15 HTML / CSS
AmazeUi Tree(树形结构) 应用小结
2020/08/17 HTML / CSS
英国女性时尚鞋类的潮流制造者:Koi Footwear
2018/10/19 全球购物
在阿联酋购买翻新手机和平板电脑:Teckzu
2021/02/12 全球购物
体育专业个人求职信范文
2013/12/27 职场文书
教师产假请假条
2014/04/10 职场文书
环保建议书200字
2014/05/14 职场文书
网络技术专业求职信
2014/07/13 职场文书
文员试用期转正自我鉴定
2014/09/14 职场文书
2014年司法局工作总结
2014/12/11 职场文书