php closure invoke,PHP Closure类详解
PHP?Closure 類是用于代表匿名函數的類,匿名函數(在 PHP 5.3 中被引入)會產生這個類型的對象,Closure類摘要如下:
Closure { __construct ( void ) public static Closure bind (Closure $closure , object $newthis [, mixed $newscope = 'static' ]) public Closure bindTo (object $newthis [, mixed $newscope = 'static' ])}
方法說明:
Closure::__construct — 用于禁止實例化的構造函數
Closure::bind — 復制一個閉包,綁定指定的$this對象和類作用域。
Closure::bindTo — 復制當前閉包對象,綁定指定的$this對象和類作用域。
除了此處列出的方法,還有一個 __invoke 方法。這是為了與其他實現了 __invoke()魔術方法 的對象保持一致性,但調用閉包對象的過程與它無關。
下面將介紹Closure::bind和Closure::bindTo。
Closure::bind是Closure::bindTo的靜態版本,其說明如下:
public static Closure bind (Closure $closure , object $newthis [, mixed $newscope = 'static' ])
closure表示需要綁定的閉包對象。
newthis表示需要綁定到閉包對象的對象,或者NULL創建未綁定的閉包。
newscope表示想要綁定給閉包的類作用域,可以傳入類名或類的示例,默認值是 ‘static’, 表示不改變。
該方法成功時返回一個新的 Closure 對象,失敗時返回FALSE。
例子說明:
<?php /** * 復制一個閉包,綁定指定的$this對象和類作用域。 * * @author 瘋狂老司機 */class Animal { private static $cat = "cat"; private $dog = "dog"; public $pig = "pig";} /* * 獲取Animal類靜態私有成員屬性 */$cat = static function() { return Animal::$cat;}; /* * 獲取Animal實例私有成員屬性 */$dog = function() { return $this->dog;}; /* * 獲取Animal實例公有成員屬性 */$pig = function() { return $this->pig;}; $bindCat = Closure::bind($cat, null, new Animal());// 給閉包綁定了Animal實例的作用域,但未給閉包綁定$this對象$bindDog = Closure::bind($dog, new Animal(), 'Animal');// 給閉包綁定了Animal類的作用域,同時將Animal實例對象作為$this對象綁定給閉包$bindPig = Closure::bind($pig, new Animal());// 將Animal實例對象作為$this對象綁定給閉包,保留閉包原有作用域echo $bindCat(),'
';// 根據綁定規則,允許閉包通過作用域限定操作符獲取Animal類靜態私有成員屬性echo $bindDog(),'
';// 根據綁定規則,允許閉包通過綁定的$this對象(Animal實例對象)獲取Animal實例私有成員屬性echo $bindPig(),'
';// 根據綁定規則,允許閉包通過綁定的$this對象獲取Animal實例公有成員屬性?>
輸出:
cat
dog
pig
Closure::bindTo?— 復制當前閉包對象,綁定指定的$this對象和類作用域,其說明如下:
public Closure Closure::bindTo (object $newthis [, mixed $newscope = 'static' ])
newthis表示綁定給閉包對象的一個對象,或者NULL來取消綁定。
newscope表示關聯到閉包對象的類作用域,可以傳入類名或類的示例,默認值是 ‘static’, 表示不改變。
該方法創建并返回一個閉包對象,它與當前對象綁定了同樣變量,但可以綁定不同的對象,也可以綁定新的類作用域。綁定的對象決定了返回的閉包對象中的$this的取值,類作用域決定返回的閉包對象能夠調用哪些方法,也就是說,此時$this可以調用的方法,與newscope類作用域相同。
例子1:
<?phpfunction __autoload($class) { require_once "$class.php";} $template = new Template;$template->render(new Article, 'tpl.php');?>
Template.php 模板類
<?php /** * 模板類,用于渲染輸出 * * @author 瘋狂老司機 */class Template{ /** * 渲染方法 * * @access public * @param obj 信息類 * @param string 模板文件名 */ public function render($context, $tpl){ $closure = function($tpl){ ob_start(); include $tpl; return ob_end_flush(); }; $closure = $closure->bindTo($context, $context); $closure($tpl); } }
Article.php 信息類
tpl.php 模板文件
<?php echo $this->title;?>
<?php echo $this->content;?>
運行時確保以上文件位于同級目錄。
輸出:
這是文章標題
這是文章內容例子2:
<?php /** * 給類動態添加新方法 * * @author 瘋狂老司機 */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 瘋狂老司機 */class Animal { use DynamicTrait; private $dog = 'dog';} $animal = new Animal; // 往動物類實例中添加一個方法獲取實例的私有屬性$dog$animal->getdog = function() { return $this->dog;}; echo $animal->getdog(); ?>
輸出:
dog
例子3:
<?php /** * 一個基本的購物車,包括一些已經添加的商品和每種商品的數量 * * @author 瘋狂老司機 */class Cart { // 定義商品價格 const PRICE_BUTTER = 1.00; const PRICE_MILK = 3.33; const PRICE_EGGS = 8.88; protected $products = array(); /** * 添加商品和數量 * * @access public * @param string 商品名稱 * @param string 商品數量 */ public function add($item, $quantity) { $this->products[$item] = $quantity; } /** * 獲取單項商品數量 * * @access public * @param string 商品名稱 */ public function getQuantity($item) { return isset($this->products[$item]) ? $this->products[$item] : FALSE; } /** * 獲取總價 * * @access public * @param string 稅率 */ public function getTotal($tax) { $total = 0.00; $callback = function ($quantity, $item) use ($tax, &$total) { $pricePerItem = constant(__CLASS__ . "::PRICE_" . strtoupper($item)); $total += ($pricePerItem * $quantity) * ($tax + 1.0); }; array_walk($this->products, $callback); return round($total, 2);; }} $my_cart = new Cart; // 往購物車里添加商品及對應數量$my_cart->add('butter', 10);$my_cart->add('milk', 3);$my_cart->add('eggs', 12); // 打出出總價格,其中有 5% 的銷售稅.echo $my_cart->getTotal(0.05); ?>
輸出:
132.88
補充說明:閉包可以使用USE關鍵連接外部變量。
總結:合理使用閉包能使代碼更加簡潔和精煉。
https://blog.csdn.net/wuxing26jiayou/article/details/51067190
總結
以上是生活随笔為你收集整理的php closure invoke,PHP Closure类详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php basic publish,Ra
- 下一篇: php注册登录遍写入 遍验证,在文件指定