当前位置:首页 > PHP教程 > php高级应用 > 列表

PHP实用小技巧之调用录像的方法

发布:smiling 来源: PHP粉丝网  添加日期:2022-01-25 20:26:51 浏览: 评论:0 

这篇文章主要给大家介绍了关于PHP实用小技巧之调用录像的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者实用PHP具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧。

主要功能

把你实际的调用操作录下来,然后在你想要的地方重新调用

和匿名函数的作用基本一样,暂存你的调用操作 一般用于链式调用, 然后实际作用于你想要操作的对象上面好像和没说一样

使用场景

假如 laravel 项目用到了 仓库模式, 然后对于比较复杂的查询条件,一般情况下有三种操作

针对特殊查询增加方法

定一个规则,按照这个规则组装数组,然后需要在 仓库类 里面实现解析

传匿名函数,匿名函数里面写查询条件

现在可以对第三种方法进行优化,传入一个下面代码里的 CallEcho 对象

  1. //控制器里 
  2. $callEcho = (new CallEcho())->where("username""马云")->where("is_boss", 1)->first(); 
  3. $fubao = (new UserRepository)->first($callEcho); 
  4.  
  5. //仓库类 
  6. class UserRepository{ 
  7.   public function first(CallEcho $callEcho){ 
  8.     return $callEcho->invoke(new User()); 
  9.   } 

看着和匿名函数差不多,但是 CallEcho 可以被继承来实现些接口,继承后还可以对查询条件进行一些操作,比如过滤什么的。用匿名函数的话,完全就看调用方的良心了。

最重要的是不传对象传函数叫什么面对对象

上代码

  1. class CallEcho 
  2.  
  3.   protected $callable = null; 
  4.  
  5.   public function __construct() 
  6.   {   
  7.     //callable 初始化 
  8.     $this->seed(); 
  9.   } 
  10.  
  11.   protected function seed(){ 
  12.     $this->callable = $this
  13.   } 
  14.  
  15.   public function __invoke($obj
  16.   { 
  17.     return $obj
  18.   } 
  19.  
  20.   public function __call($name$arguments
  21.   { 
  22.     $current = $this->callable; 
  23.     /** 
  24.      * 每产生__call,就往callable上面裹一层 
  25.      */ 
  26.     $this->callable = function($objuse($name$arguments$current){ 
  27.       return call_user_func_array($current, [$obj])->{$name}(...$arguments); 
  28.     }; 
  29.     return $this
  30.   } 
  31.     
  32.   //作用于真正的对象上面 
  33.   public function invoke($obj){ 
  34.     return call_user_func_array($this->callable, [$obj]); 
  35.   } 

简单的测试 以及 使用

  1. class TestCallEcho{ 
  2.   protected $called = []; 
  3.  
  4.   public function __call($name$arguments
  5.   { 
  6.     $this->called[] = [$name$arguments]; 
  7.     return $this
  8.   } 
  9.  
  10.   public function end(){ 
  11.     $this->called[] = "end"
  12.     return $this
  13.   } 
  14.  
  15.   public function getCalled(){ 
  16.     return $this->called; 
  17.   } 
  18.  
  19. function testArrayEq($array1$array2){ 
  20.   if(count($array1) !== count($array2)){ 
  21.     return false; 
  22.   } 
  23.  
  24.   foreach ($array1 as $index => $value1){ 
  25.     if(!isset($array2[$index])){ 
  26.       return false; 
  27.     } 
  28.     $value2 = $array2[$index]; 
  29.  
  30.     if(is_array($value1) && is_array($value2)){ 
  31.       if(!testArrayEq($value1$value2)){ 
  32.         return false; 
  33.       }else
  34.         //继续判断 
  35.       } 
  36.     }else
  37.       if($value1 !== $value2){ 
  38.         return false; 
  39.       } 
  40.     } 
  41.   } 
  42.   return true; 
  43.  
  44. function testTestArrayEq(){ 
  45.   $array1 = [1, 2]; 
  46.   $array2 = [1, 3]; 
  47.   $array3 = [1, 2, 3]; 
  48.  
  49.   assert(testArrayEq($array1$array2) == false); 
  50.   assert(testArrayEq($array1$array3) == false); 
  51.   assert(testArrayEq($array1$array1) == true); 
  52. testTestArrayEq(); 
  53.  
  54. $obj = new \stdClass(); 
  55. $callEcho = new CallEcho(); 
  56.  
  57. /*************重点开始****************/ 
  58. /** @var CallEcho $callEcho */ 
  59. $callEcho = $callEcho->testNumber(1)->testString("myname")->testObj($obj)->testMulti(1, "myname")->testMulti2("1"$obj)->end(); 
  60.  
  61. /** @var TestCallEcho $testCallEcho */ 
  62. $testCallEcho = $callEcho->invoke(new TestCallEcho()); 
  63. /************重点结束****************/ 
  64.  
  65. //基本上和这个作用一样 
  66. $a = function($obj){ 
  67.   $obj->testNumber(1)->testString("myname")->testObj($obj)->testMulti(1, "myname")->testMulti2("1"$obj)->end(); 
  68. }; 
  69.  
  70.  
  71. $called = $testCallEcho->getCalled(); 
  72.  
  73. $eq = testArrayEq($called, [ 
  74.   ["testNumber", [1]], 
  75.   ["testString", ["myname"]], 
  76.   ["testObj", [$obj]], 
  77.   ["testMulti", [1, "myname"]], 
  78.   ["testMulti2", ["1"$obj]], 
  79.   "end" 
  80. ]); 
  81. assert($eq); 

PS

灵感来源于slim3 中间件 的实现

Tags: PHP调用录像

分享到: