类结构
Closure { /* 方法 */ // 用于禁止实例化的构造函数 __construct ( void ) // 复制一个闭包,绑定指定的$this对象和类作用域。 public static Closure bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] ) // 复制当前闭包对象,绑定指定的$this对象和类作用域。 public Closure bindTo ( object $newthis [, mixed $newscope = 'static' ] )}// 类作用域,可以是对象,也可以是实例名称
什么是匿名类?
先理解以下三个例子
例1. 闭包函数都是继承Closure类
class A { public static function testA() { return function($i) { //返回匿名函数 return $i+100; }; }}function B(Closure $callback){ return $callback(200);}$a = B(A::testA());// A::testA() 返回匿名函数,也就是闭包函数,所有闭包函数都是继承Closure类// print_r($a); //输出 300
例2. 将一个匿名函数绑定到一个类中。返回Closure类
class A { public $base = 100; public function funca() { echo 2222; }}class B { private $base = 1000;}// bind : 复制一个闭包,绑定指定的$this对象和类作用域。$f = function () { return $this->base + 3;};print_r($f);/** * $f其实就是一个closure对象 Closure Object ( ) */$a = Closure::bind($f, new A);print_r($a());//out: 103print_r($a);/* * out: Closure Object ( [this] => A Object ( [base] => 100 ) ) */// 第三个参数就声明了这个函数的可调用范围(如果该函数要调用private), 该参数可以是对象实例,也可以是类名$b = Closure::bind($f, new B, 'B');print_r($b);/** * out:Closure Object ( [this] => B Object ( [base:B:private] => 1000 )) */print_r($b());//out: 1003
3. 第二参数为null,代表静态调用static
class A { private static $sfoo = 1; private $ifoo = 2;}// 要调静态的属性,就必须声明static$cl1 = static function() { return A::$sfoo;};$cl2 = function() { return $this->ifoo;};// 第二参数为null,就代表调用static$bcl1 = Closure::bind($cl1, null, 'A');$bcl2 = Closure::bind($cl2, new A(), 'A');// 以closure对象调用静态属性$bcl3 = $cl1->bindTo(null,'A');echo $bcl1(), "\n";//输出 1echo $bcl2(), "\n";//输出 2echo $bcl3(); // 输出1
匿名类有什么用?
给类动态添加新方法
trait DynamicTrait { /** * 自动调用类中存在的方法 */ public function __call($name, $args) { if(is_callable($this->$name)){ return call_user_func($this->$name, $args); }else{ throw new \RuntimeException("Method {$name} does not exist"); } } /** * 添加方法 */ public function __set($name, $value) { $this->$name = is_callable($value)? $value->bindTo($this, $this): $value; }}/** * 只带属性不带方法动物类 * * @author fantasy */class Animal { use DynamicTrait; private $dog = '汪汪队';}$animal = new Animal;// 往动物类实例中添加一个方法获取实例的私有属性$dog$animal->getdog = function() { return $this->dog;};echo $animal->getdog();//输出 汪汪队
模板渲染输出
Template.php
class Template{ /** * 渲染方法 * * @access public * @param obj 信息类 * @param string 模板文件名 */ public function render($context, $tpl){ $closure = function($tpl){ ob_start(); include $tpl; return ob_end_flush(); }; // PHP7: $closure->call($context, $tpl); $closure = $closure->bindTo($context, $context); $closure($tpl); }}
Article.php
/** * 文章信息类 */class Article{ private $title = "这是文章标题"; private $content = "这是文章内容";}
tpl.php
······<body><h1><?php echo $this->title;?></h1><p><?php echo $this->content;?></p></body>······
index.php
function __autoload($class) { require_once "$class.php";}$template = new Template;$template->render(new Article, 'tpl.php');
PHP7 新增的call方法
class Value{ protected $value; public function __construct($value) { $this->value = $value; } public function getValue() { return $this->value; }}$three = new Value(3);$four = new Value(4);$closure = function ($delta){ return $this->getValue() + $delta;};/** * function call ($newThis, ...$parameters) * 把$closure绑定到$three,并调用;第二参数起就是闭包的参数 */echo $closure->call($three , 3);echo PHP_EOL;echo $closure->call($four , 4);