类结构

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: 103

print_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";//输出 1

echo $bcl2(), "\n";//输出 2

echo $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

···

···

<?php echo $this->title;?>

<?php echo $this->content;?>

···

···

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);

php匿名类的应用场景,【modernPHP专题(9)】匿名类相关推荐

  1. C++ 类的知识 | 构造函数再探、匿名对象、友元函数、内部类、类的const成员、类的static成员

    文章目录 构造函数再探 以下代码共调用多少次拷贝构造函数 委托构造函数 概念 形式 匿名对象 友元 友元的声明 友元类 令成员函数作为友元 函数重载和友元 注意 内部类 特性 类的const成员 可变 ...

  2. Java原子操作类AtomicInteger应用场景

    参考文章:Java原子操作类AtomicInteger应用场景 感谢作者分享!

  3. 专题---自定义实体类

    目录 一.概述 二.项目初始化 2.1 创建空解决方案 2.2 DBX操作 2.2.1 创建DBX 2.2.2 调试DBX 2.2.3 创建实体类 2.2.4 调试实体类 2.3 ARX操作 2.3. ...

  4. IDEA常用场景搜索快捷键(当前类、当前项目、全局)

    在IDEA中,最常用的搜索方式是shift双击触发全局搜索,https://blog.csdn.net/SSHLY3/article/details/121274759?spm=1001.2014.3 ...

  5. 类的初始化列表_【Flutter 111】Flutter手把手教程Dart语言——类、类的的成员变量和方法、类的构造函数...

    类 Dart是一种面向对象的语言,所有对象都是一个类的实例,而所有的类都继承自Object类.每个除了Object类之外的类都只有一个超类,一个类的代码可以在其它多个类继承中重复使用. 类的实例变量 ...

  6. java 类的访问权限_什么是Java类的访问权限?

    展开全部 在解32313133353236313431303231363533e59b9ee7ad9431333366306436释访问权限控制之前,先看一个场景. 在学生信息管理系统中,有两个类,分 ...

  7. mave工程中的一个类调用另一个聚合工程的一个类_信息系统管理工程师备考分享(材料重点精炼)——第一章信息化和信息系统(4)...

    本章分享的1.4节的重要考点内容相对来说还是比较多的,里面包括需求.设计.测试等软件工程的内容,同学们学完前几篇文章的分享会发现,第一章与计算机领域的知识的衔接程度还是非常紧密的.我经常会听到很多面授 ...

  8. 八类网线和七类网线的区别_什么是七类网线?七类网线水晶头如何制作?

    要了解七类网线如何使用?需要掌握这四个问题: 1.什么是七类网线? 2.七类网线与六类网线有什么区别? 3.七类网线用什么水晶头?如何制作7类网线水晶头? 4.7类网线的应用场景? 带着这四个问题,我 ...

  9. JAVA类思维_面向对象思维 Java中的类和对象及其应用

    一.面向过程与面向对象 面向过程: 从事务执行者的角度思考问题,我该干什么  重点在过程----事务流程 面向对象: 从事务的指挥者角度思考问题,我应该找谁干什么  重点在对象 面向对象的优点: 1. ...

  10. java aes 工具类_Java中的AES加解密工具类:AESUtils

    本人手写已测试,大家可以参考使用 package com.mirana.frame.utils.encrypt; import com.mirana.frame.constants.SysConsta ...

最新文章

  1. 如何卸载iPhone模拟器中的自己创建的程序
  2. Abbreviation
  3. 第四章:Java_面向对象编程(二)
  4. 双向口 与 准双向口 区别
  5. mysql 最近_关于mysql查询最近一条记录
  6. Unitest框架的使用(一)准备工作,接口定义和Unittest方法
  7. pyintaller exe 后 print的内容 怎么体现_使用Github Actions自动化构建exe
  8. Linux 3g上网卡 拨号,Ubuntu 3G上网卡拨号过程分析
  9. 20165230 2017-2018-2 《Java程序设计》第8周学习总结
  10. OSI参考模型及其数据封装和解封装介绍
  11. 网络请求statusCode(状态码) 200、300、400、500序列
  12. linux嵌入式缺点,嵌入式领域linux作为实时操作系统的缺点
  13. ​学习C语言的知识点整理
  14. Lambda表达式与函数式接口详解
  15. yocto之相关class总结
  16. 软件测试人员需不需要懂代码
  17. 输入国家名按字典顺序进行排序
  18. 使用GDScript(godot)生成仿杀戮尖塔地图
  19. 不是python文件操作的相关函数_从零开始学Python(七):文件存储I/O流和异常捕捉
  20. 【读书笔记】《心流:最优体验心理学》——序

热门文章

  1. cell操作-matlab
  2. Codeforces Round #590 (Div. 3) E. Special Permutations 差分 + 思维
  3. Codeforces Round #723 (Div. 2) D. Kill Anton 线段树 + 暴力
  4. ARC078F - Mole and Abandoned Mine(状压DP)
  5. 【模板】差分约束算法
  6. 牛客题霸 反转链表 C++题解/答案
  7. [ZJOI2007] 棋盘制作(单调栈 / DP悬线法)
  8. BZOJ #3166. [Heoi2013]Alo(可持久化trie树+set)
  9. [2021-09-11 CQBZ/HSZX多校联考 T1] 茅山道术 (后缀和优化dp)
  10. YBTOJ:单词频率(AC自动机)