20.php回撥、匿名函式、和閉包操作
阿新 • • 發佈:2019-01-22
現在的php是即支援面向物件的語言由支援面向過程的語言,在開發過程中我們往往會混合使用,回撥會讓我們容易將兩種編碼方式做整合,做到優秀的插拔。而閉包操作和回撥都是建立在匿名函式基礎之上的。
<?php /* 簡單的用於實驗的類 */ class Product{ public $name; public $price; function __construct($name, $price){ $this->name = $name; $this->price = $price; } } class ProcessSale{ //用來存放函式 private $callbacks = array(); //使用is_callable()在存入陣列之前對函式的可用性進行檢測 function registerCallback($callback){ if(!is_callable($callback)){ throw new Exception("callback not callable!"); } $this->callbacks[] = $callback; } //方便對函式的呼叫 function sale(Product $product){ print "{$product->name}:processing<br/>"; foreach ($this->callbacks as $callback){ call_user_func($callback, $product); } } } //被插入的函式 function say($product){ echo "{$product->name}"; } $product = new Product('xin', 100); $process = new ProcessSale(); $process->registerCallback('say'); $process->sale($product);
那麼匿名函式是什麼樣的呢?
使用變數存放的型別,注意雖然有分行但是,最後結束還是要使用“;”,另外呼叫的時候要使用變數名,而不是函式名的字串的形式。
//被插入的函式
$say = function ($product){
echo "{$product->name}";
};
$process->registerCallback($say);
使用create_function()函式建立的型別。同樣要注意上面提到的兩點。
下面來說一說閉包的問題。$say = create_function('$product', 'echo "{$product->name}";'); $process->registerCallback($say);
所謂的閉包,是一種對作用域進行封裝的方式,使得函式能使用父作用域中的變數。
有時候我們能將匿名函式直接返回。
class Totalizer{
static function warnAmount(){
return function($product){
echo $product->name;
};
}
}
$process->registerCallback(Totalizer::warnAmount());
現在我們要對商品進行總額計價,並當商品總價格超出某一值時進行提示
全部程式碼
<?php
/* 簡單的用於實驗的類 */
class Product{
public $name;
public $price;
function __construct($name, $price){
$this->name = $name;
$this->price = $price;
}
}
class ProcessSale{
//用來存放函式
private $callbacks = array();
//使用is_callable()在存入陣列之前對函式的可用性進行檢測
function registerCallback($callback){
if(!is_callable($callback)){
throw new Exception("callback not callable!");
}
$this->callbacks[] = $callback;
}
//方便對函式的呼叫
function sale(Product $product){
print "{$product->name}:processing<br/>";
foreach ($this->callbacks as $callback){
call_user_func($callback, $product);
}
}
}
class Totalizer{
static function warnAmount($amt){
$count = 0;
return function($product) use ($amt, &$count){
$count += $product->price;
print "all count: $count<br/><br/>";
if($count > $amt){
echo "warring!!!!!!";
}
};
}
}
//被插入的函式
/* $say = function ($product){
echo "{$product->name}";
}; */
$say = create_function('$product', 'echo "{$product->name}";');
$product = new Product('xin', 10);
$process = new ProcessSale();
$process->registerCallback(Totalizer::warnAmount(30));
$process->sale($product);
$process->sale($product);
$process->sale($product);
$process->sale($product);
Totalizer的warnAmount方法返回一個匿名函式,匿名函式中明確說明要使用類方法中的$amt和$count兩個變數,這就是閉包操作,對父域中的變數的使用。