## 類結構
```php
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類
```php
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類
```php
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
```php
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
```
## 匿名類有什么用?
### 給類動態添加新方法
```php
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**
```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**
```php
/**
* 文章信息類
*/
class Article
{
private $title = "這是文章標題";
private $content = "這是文章內容";
}
```
**tpl.php**
```php
···
···
<body>
<h1><?php echo $this->title;?></h1>
<p><?php echo $this->content;?></p>
</body>
···
···
```
**index.php**
```php
function __autoload($class) {
require_once "$class.php";
}
$template = new Template;
$template->render(new Article, 'tpl.php');
```
## PHP7 新增的call方法
```php
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特性
- php7常用特性整理
- 反射機制Reflection
- 依賴注入與服務容器
- 抽象類與接口
- 類多繼承的替代方案Traits
- 類的延遲綁定(后期綁定)
- 生成器語法
- 匿名函數和閉包
- 匿名類
- 理解php的output buffer
- 斷言ASSERT
- 魔術方法小結
- Zend Opcache字節碼緩存
- 內置的http服務器
- SPL標準庫
- 【SPL標準庫專題(1)】SPL簡介
- 【SPL標準庫專題(2)】Iterator
- 【SPL標準庫專題(3)】Classes
- 【SPL標準庫專題(4)】Exceptions
- 【SPL標準庫專題(5)】Datastructures:SplDoublyLinkedList
- 【SPL標準庫專題(6)】Datastructures:SplStack & SplQueue
- 【SPL標準庫專題(7)】Datastructures:SplPriorityQueue
- 【SPL標準庫專題(8)】Datastructures:SplHeap & SplMaxHeap & SplMinHeap
- 【SPL標準庫專題(9)】Datastructures:SplFixedArray
- 【SPL標準庫專題(10)】Datastructures:SplObjectStorage
- PHPcomposer使用手札[ing]
- PHP中的多態
- 通過命名空間實現自動加載的框架雛形
- 日期與金額
- PHPstorm使用攻略
- 筆記本