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 相关文章推荐
一个SQL管理员的web接口
Oct 09 PHP
php之对抗Web扫描器的脚本技巧
Oct 01 PHP
在PHP中养成7个面向对象的好习惯
Jan 28 PHP
PHP多线程批量采集下载美女图片的实现代码(续)
Jun 03 PHP
关于php操作mysql执行数据库查询的一些常用操作汇总
Jun 24 PHP
提升PHP性能的21种方法介绍
Jun 25 PHP
php数组中删除元素之重新索引的方法
Sep 16 PHP
WordPress中给媒体文件添加分类和标签的PHP功能实现
Dec 31 PHP
Yii2实现ajax上传图片插件用法
Apr 28 PHP
php微信开发之百度天气预报
Nov 18 PHP
PHP仿qq空间或朋友圈发布动态、评论动态、回复评论、删除动态或评论的功能(上)
May 26 PHP
PHP7创建销毁session的实例方法
Feb 03 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开发框架kohana3 自定义路由设置示例
2014/07/14 PHP
如何让thinkphp在模型中自动完成session赋值小教程
2014/09/05 PHP
PHP弱类型的安全问题详细总结
2016/09/25 PHP
PHP 断点续传实例详解
2017/11/11 PHP
PHP中的self关键字详解
2019/06/23 PHP
js取滚动条的尺寸的函数代码
2011/11/30 Javascript
js自定义事件及事件交互原理概述(二)
2013/02/01 Javascript
a标签的href和onclick 的事件的区别介绍
2013/07/26 Javascript
JavaScript遍历table表格中的某行某列并打印其值
2014/07/08 Javascript
在JavaScript中构建ArrayList示例代码
2014/09/17 Javascript
javascript实现可键盘控制的抽奖系统
2016/03/10 Javascript
Jquery组件easyUi实现选项卡切换示例
2016/08/23 Javascript
简单实现js倒计时功能
2017/02/13 Javascript
javascript简单链式调用案例分析
2017/05/10 Javascript
JavaScript设计模式之策略模式详解
2017/06/09 Javascript
解决Vue编译时写在style中的路径问题
2017/09/21 Javascript
vue中如何动态绑定图片,vue中通过data返回图片路径的方法
2018/02/07 Javascript
JavaScript(js)处理的HTML事件、键盘事件、鼠标事件简单示例
2019/11/19 Javascript
非常漂亮的js烟花效果
2020/03/10 Javascript
JS性能优化实现方法及优点进行
2020/08/30 Javascript
[44:50]2018DOTA2亚洲邀请赛 4.1 小组赛 A组 TNC vs VG
2018/04/02 DOTA
Python自定义scrapy中间模块避免重复采集的方法
2015/04/07 Python
python字符串过滤性能比较5种方法
2017/06/22 Python
python3 发送任意文件邮件的实例
2018/01/23 Python
python numpy 常用随机数的产生方法的实现
2019/08/21 Python
浅谈keras中的keras.utils.to_categorical用法
2020/07/02 Python
python中如何使用虚拟环境
2020/10/14 Python
python爬虫使用scrapy注意事项
2020/11/23 Python
GAP阿联酋官网:GAP UAE
2017/11/30 全球购物
测试时代收集的软件测试面试题
2013/09/25 面试题
大专自我鉴定范文
2013/10/23 职场文书
求职信模版
2013/11/30 职场文书
小学毕业家长寄语
2014/01/19 职场文书
实习护士自荐信
2015/03/25 职场文书
2017年寒假社区服务活动总结
2016/04/06 职场文书
广告策划的实习心得体会总结!
2019/07/22 职场文书