ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
1.Closure,匿名函数 ``` <? $func = function( $param ) { echo $param; }; $func( 'hello word' ); //输出:hello word ``` ~~~ <?php $f = function () { return 100; }; function B(Closure $callback) { return $callback(); } $a = B($f); print_r($a);//输出100 ~~~ 2. 闭包 将匿名函数在普通函数中当做参数传入,也可以被返回。这就实现了一个简单的闭包。 ~~~ <?php //例一 //在函数里定义一个匿名函数,并且调用它 function printStr() { $func = function( $str ) { echo $str; }; $func( ' hello my girlfriend ! ' ); } printStr();//输出 hello my girlfriend ! //例二 //在函数中把匿名函数返回,并且调用它 function getPrintStrFunc() { $func = function( $str ) { echo $str; }; return $func; } $printStrFunc = getPrintStrFunc(); $printStrFunc( ' do you love me ? ' );//输出 do you love me ? //例三 //把匿名函数当做参数传递,并且调用它 function callFunc( $func ) { $func( ' no!i hate you ' ); } $printStrFunc = function( $str ) { echo $str.'<br>'; }; callFunc( $printStrFunc ); ## 连接闭包和外界变量的关键字:USE 闭包可以保存所在代码块上下文的一些变量和值。PHP在默认情况下,匿名函数不能调用所在代码块的上下文变量,而需要通过使用use关键字 function getMoney() { $rmb = 1; $dollar = 8; $func = function() use ( $rmb ) { echo $rmb; echo $dollar; }; $func(); } getMoney(); //输出:1 use所引用的也只不过是变量的一个副本clone而已。但是我想要完全引用变量,而不是复制呢?要达到这种效果,其实在变量前加一个 & 符号就可以了:如果将匿名函数返回给外界,匿名函数会保存use所引用的变量,而外界则不能得到这些变量 function getMoneyFunc() { $rmb = 1; $func = function() use ( &$rmb ) { echo $rmb.'<br>'; //把$rmb的值加1 $rmb++; }; return $func; } $getMoney = getMoneyFunc(); $getMoney(); $getMoney(); $getMoney(); //输出: //1,//2,//3 ~~~ ~~~ <?php class A { public static function testA() { return function($i) { //返回匿名函数 return $i+100; }; } } function B(Closure $callback) { return $callback(200); } $a = B(A::testA()); print_r($a);//输出 300 其中的A::testA()返回的就是一个无名funciton。 ~~~ 3.Closure闭包之Closure :: call - 绑定并调用闭包----php7以上 ``` <?php class A { private $x = 1; } // PHP 7+ code, Define $value = function() { return $this->x; }; print($value->call(new A)); ?> 输出:1 ``` 4.# 依赖注入的理解 所谓依赖,举个例子说明,一个类Person,另一个类Car,如果Person的某个方法比如说drive,需要引用Car,则称Person类依赖于 Car类,延伸到对象,这种依赖关系依然成立 ~~~ <?php class C { public function doSomething() { echo __METHOD__, '我是C类|'; } } class B { private $c; public function __construct(C $c) { $this->c = $c; } public function doSomething() { $this->c->doSomething(); echo __METHOD__, '我是B类|'; } } class A { private $b; public function __construct(B $b) { $this->b = $b; } public function doSomething() { $this->b->doSomething(); echo __METHOD__, '我是A类|';; } } $class = new A(new B(new C())); $class->doSomething(); // C::doSomething我是C类|B::doSomething我是B类|A::doSomething我是A类| ~~~ 5.容器 ``` <?php class Test{ public $instances=[]; protected static $instance; private function __construct(){ } //实例化本身 public static function getInstance(){ if(is_null(static::$instance)){ static::$instance=new static; } return static::$instance; } 向容器注入类 public function set($key,$value){ $this->instances[$key]=$value; } /* 通过反射机制获取容器里面的实例 */ public function get($key){ if($this->instances[$key]){ $key=$this->instances[$key]; } $reflect=new \ReflectionClass($key); $c=$reflect->getConstructor(); if(!$c){ return new $key; } $params=$c->getParameters(); if(empty($params)){ return new $key; } foreach ($params as $param) { $class=$param->getClass(); if(!$class){ }else{ $args[]=$this->get($class->name); } } return $reflect->newInstanceArgs($args); } } 调用: public function index(){ \Test::getInstance()->set('Person','\Person'); 注入Person类 \Test::getInstance()->set('Car','\Car'); $obj1=\Test::getInstance()->get('Person'); 获取Person类 $obj2=\Test::getInstance()->get('Car'); echo $obj1->buy($obj2); //依赖注入 } ``` 6.门面 门面模式,是指提供一个统一的接口去访问多个子系统的多个不同的接口,它为子系统中的一组接口提供一个统一的高层接口。使得子系统更容易使用 1.定义一个(或多个)具备所需接口的新类(门面类Facade) 2.新类门户(门面类Facade)使用原来的系统(包含Hotel,Traffic,ScenicArea三个类) 3.客户使用门面类对象与原系统打交道(客户端只调用Facade)