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
php巧获服务器端信息
Dec 06 PHP
php 全文搜索和替换的实现代码
Jul 29 PHP
php多文件上传下载示例分享
Feb 20 PHP
php随机生成数字字母组合的方法
Mar 18 PHP
phpcms手机内容页面添加上一篇和下一篇
Jun 05 PHP
我整理的PHP 7.0主要新特性
Jan 07 PHP
PHP获取网站中各文章的第一张图片的代码示例
May 20 PHP
浅谈PHP定义命令空间的几个注意点(推荐)
Oct 29 PHP
PHP调用API接口实现天气查询功能的示例
Sep 21 PHP
PHP堆栈调试操作简单示例
Jun 15 PHP
Thinkphp5.0框架使用模型Model的获取器、修改器、软删除数据操作示例
Oct 11 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实现无限级分类实现代码(递归方法)
2011/01/01 PHP
探讨PHP调用时间格式的参数详解
2013/06/06 PHP
PHP 验证登陆类分享
2015/03/13 PHP
使用PHP如何实现高效安全的ftp服务器(一)
2015/12/20 PHP
PHP类的声明与实例化及构造方法与析构方法详解
2016/01/26 PHP
php项目开发中用到的快速排序算法分析
2016/06/25 PHP
php使用ftp实现文件上传与下载功能
2017/07/21 PHP
在IE中调用javascript打开Excel的代码(downmoon原作)
2007/04/02 Javascript
javascript实现字符串反转的方法
2015/02/05 Javascript
JavaScript实现刷新不重记的倒计时
2016/08/10 Javascript
Vue render渲染时间戳转时间,时间转时间戳及渲染进度条效果
2018/07/27 Javascript
layer.open组件获取弹出层页面变量、函数的实例
2019/09/25 Javascript
小程序实现按下录音松开识别语音
2019/11/22 Javascript
ckeditor一键排版功能实现方法分析
2020/02/06 Javascript
mpvue网易云短信接口实现小程序短信登录的示例代码
2020/04/03 Javascript
举例讲解Python中字典的合并值相加与异或对比
2016/06/04 Python
Python爬虫DNS解析缓存方法实例分析
2017/06/02 Python
Python2.7基于笛卡尔积算法实现N个数组的排列组合运算示例
2017/11/23 Python
Python实现的读取电脑硬件信息功能示例
2018/05/30 Python
深入理解Django-Signals信号量
2019/02/19 Python
python 判断文件还是文件夹的简单实例
2019/06/10 Python
Python3 中sorted() 函数的用法
2020/03/24 Python
如何使用python-opencv批量生成带噪点噪线的数字验证码
2020/12/21 Python
可以随进度显示不同颜色的css3进度条分享
2014/04/11 HTML / CSS
德国婴儿推车和儿童安全座椅商店:BABYSHOP
2016/09/01 全球购物
马来西亚银饰品牌:JEOEL
2017/12/15 全球购物
房地产销售员的自我评价分享
2013/12/04 职场文书
简历中的自我评价范文
2014/02/05 职场文书
集体婚礼策划方案
2014/02/22 职场文书
2014年重阳节敬老活动方案
2014/09/16 职场文书
学习十八大标语
2014/10/09 职场文书
2014年化工厂工作总结
2014/11/25 职场文书
2014年酒店年度工作总结
2014/12/10 职场文书
婚庆公司开业主持词
2015/06/30 职场文书
小学语文教师研修感悟
2015/11/18 职场文书
中国古代史学名著《战国策》概述
2019/08/09 职场文书