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面向对象的方法重载两种版本比较
Sep 08 PHP
IIS6+PHP5+MySQL5+Zend Optimizer+phpMyAdmin安装配置图文教程 2009年
Jun 08 PHP
PHP 基本语法格式
Dec 15 PHP
php从字符串创建函数的方法
Mar 16 PHP
php使用array_search函数实现数组查找的方法
Jun 12 PHP
PHP微信刮刮卡 附微信接口
Jul 22 PHP
Thinkphp微信公众号支付接口
Aug 04 PHP
php微信公众平台开发(三)订阅事件处理
Dec 06 PHP
php结合redis高并发下发帖、发微博的实现方法
Dec 15 PHP
Ajax请求PHP后台接口返回信息的实例代码
Aug 21 PHP
Thinkphp 在api开发中异常返回依然是html的解决方式
Oct 16 PHP
ThinkPHP5和ThinkPHP6的区别
Mar 31 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
变量在 PHP7 内部的实现(二)
2015/12/21 PHP
用JavaScript实现UrlEncode和UrlDecode的脚本代码
2008/07/23 Javascript
jquery中的事件处理详细介绍
2013/06/24 Javascript
javaScript arguments 对象使用介绍
2013/10/18 Javascript
jQuery实现hover合成事件的方法
2015/08/06 Javascript
jacascript DOM节点——元素节点、属性节点、文本节点
2017/04/18 Javascript
JavaScript实现隐藏省略文字效果的方法
2017/04/27 Javascript
Node.js使用orm2进行update操作时关联字段无法修改的解决方法
2017/06/13 Javascript
Vue 源码分析之 Observer实现过程
2018/03/29 Javascript
详解操作虚拟dom模拟react视图渲染
2018/07/25 Javascript
小程序云开发获取不到数据库记录的解决方法
2019/05/18 Javascript
解决Layui数据表格显示无数据提示的问题
2019/11/14 Javascript
Js Snowflake(雪花算法)生成随机ID的实现方法
2020/08/26 Javascript
[47:22]Mineski vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
[56:42]VP vs RNG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
python正则匹配抓取豆瓣电影链接和评论代码分享
2013/12/27 Python
Windows系统下安装Python的SSH模块教程
2015/02/05 Python
Python中强大的命令行库click入门教程
2016/12/26 Python
python利用paramiko连接远程服务器执行命令的方法
2017/10/16 Python
对python文件读写的缓冲行为详解
2019/02/13 Python
在Python中画图(基于Jupyter notebook的魔法函数)
2019/10/28 Python
基于Python把网站域名解析成ip地址
2020/05/25 Python
python判断一个变量是否已经设置的方法
2020/08/13 Python
python基于Kivy写一个图形桌面时钟程序
2021/01/28 Python
pip/anaconda修改镜像源,加快python模块安装速度的操作
2021/03/04 Python
HTML5 和小程序实现拍照图片旋转、压缩和上传功能
2018/10/08 HTML / CSS
Myprotein蛋白粉美国官网:欧洲畅销运动营养品牌
2016/11/15 全球购物
巴基斯坦电子产品购物网站:Home Shopping
2017/09/14 全球购物
十佳护士先进事迹
2014/05/08 职场文书
涉密人员保密承诺书
2014/05/28 职场文书
个人委托书范本汇总
2014/10/01 职场文书
2014年幼儿园教师工作总结
2014/11/08 职场文书
Nginx访问日志及错误日志参数说明
2021/03/31 Servers
OpenCV-Python实现油画效果的实例
2021/06/08 Python
SQL Server内存机制浅探
2022/04/06 SQL Server
Python实现仓库管理系统
2022/05/30 Python