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版自动生成文章摘要
Jul 23 PHP
PHP 操作文件的一些FAQ总结
Feb 12 PHP
浅谈php中mysql与mysqli的区别分析
Jun 10 PHP
Codeigniter购物车类不能添加中文的解决方法
Nov 29 PHP
php截取指定2个字符之间字符串的方法
Apr 15 PHP
PHP基于文件存储实现缓存的方法
Jul 20 PHP
PHP如何通过AJAX方式实现登录功能
Nov 23 PHP
详解PHP中array_rand函数的使用方法
Sep 11 PHP
PHP简单实现冒泡排序的方法
Dec 26 PHP
PHP实现的数据对象映射模式详解
Mar 20 PHP
PHP数据对象映射模式实例分析
Mar 29 PHP
浅析PHP 中move_uploaded_file 上传中文文件名失败
Apr 17 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中SESSION使用中的一点经验总结
2012/03/30 PHP
CodeIgniter配置之config.php用法实例分析
2016/01/19 PHP
深入理解PHP的远程多会话调试
2017/09/21 PHP
Yii框架分页技术实例分析
2019/08/30 PHP
thinkPHP事务操作简单案例分析
2019/10/17 PHP
来自chinaz的ajax获取评论代码
2008/05/03 Javascript
线路分流自动智能跳转代码,自动选择最快镜像网站(js)
2011/10/31 Javascript
ajax java 实现自动完成功能
2012/12/19 Javascript
简约JS日历控件 实例代码
2013/07/12 Javascript
javascript:void(0)是什么意思示例介绍
2013/11/17 Javascript
JavaScript实现页面跳转的方式汇总
2016/05/16 Javascript
Javascript 调用 ActionScript 的简单方法
2016/09/22 Javascript
实现div滚动条默认最底部以及默认最右边的示例代码
2017/11/15 Javascript
jquery中ajax请求后台数据成功后既不执行success也不执行error的完美解决方法
2017/12/24 jQuery
vue在手机中通过本机IP地址访问webApp的方法
2018/08/15 Javascript
全面解析JavaScript Module模式
2020/07/24 Javascript
解决Antd 里面的select 选择框联动触发的问题
2020/10/24 Javascript
在Python中使用Mako模版库的简单教程
2015/04/08 Python
Python实现屏幕截图的代码及函数详解
2016/10/01 Python
用Python和WordCloud绘制词云的实现方法(内附让字体清晰的秘笈)
2019/01/08 Python
Python 多个图同时在不同窗口显示的实现方法
2019/07/07 Python
python 读写文件包含多种编码格式的解决方式
2019/12/20 Python
Canvas绘制浮动球效果的示例
2017/12/29 HTML / CSS
中国酒类在线零售网站:酒仙网
2016/08/20 全球购物
Kaufmann Mercantile官网:家居装饰、配件、户外及更多
2018/09/28 全球购物
一份全面的PHP面试问题考卷
2012/07/15 面试题
标记环介质访问控制协议
2016/03/27 面试题
合作意向书
2014/07/30 职场文书
环境工程专业毕业生求职信
2014/09/30 职场文书
超市工作总结范文2014
2014/12/19 职场文书
中英文求职信范文
2015/03/19 职场文书
学校元旦晚会开场白
2015/05/29 职场文书
演讲开头怎么书写?
2019/08/06 职场文书
解决python3安装pandas出错的问题
2021/05/20 Python
Python与C++中梯度方向直方图的实现
2022/03/17 Python
Python+OpenCV实现图片中的圆形检测
2022/04/07 Python