现在的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两个变量,这就是闭包操作,对父域中的变量的使用。