当前位置:首页 > 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.   } 
  10. } 

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

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

上代码

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

简单的测试 以及 使用

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

PS

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

Tags: PHP调用录像

分享到: