回调 匿名函数和闭包
/**
* Created by PhpStorm.
* User: mali@mali
* Date: 2020/8/3
* Time: 4:46 下午
*/
class mysql{
public static function getlist($demo)
{
echo $demo;
}
}
//回调静态方法
call_user_func(['mysql','getlist'],'params');
echo "
";
$cal = new mysql();
//回掉普通方法
call_user_func([$cal,"getlist"],"class");
echo "
";
function test($a,$b)
{
echo "love"."----".$a."----".$b."
";
}
//回调方法
call_user_func('test','star','shine');
回调有什么用呢?它允许程序在运行期间将与组件核心任务没有直接关系的功能“插入“组件。通过让组件拥有回调能力,可以赋予其他程序员在我们不知道的上下文中扩展代码的能力。
假设ProcessSale类的客户端程序员希望创建一条销售记录。如果改程序员可以修改这个类,这一版是不可行的。就算他是包的维护者,在sale()方法中加入许多附带功能也会干扰它的核心职责。
所以我们可以让ProcessSale创建一个回掉的功能。然后将我们自己需要的逻辑放入外面的方法,通过回掉的方式机进行访问。
/**
* 创建普通的匿名函数
* Created by PhpStorm.
* User: mali@mali
* Date: 2020/8/3
* Time: 3:11 下午
*/
class product{
public $name;
public $price;
public function __construct(string $name,float $price)
{
$this->name = $name;
$this->price = $price;
}
}
class ProcessSale{
private $callbacks;
public function registerCallback(callable $callback)
{
if(! is_callable($callback)){
throw new Exception("callable not callable");
}
$this->callbacks[] = $callback;
}
public function sale(product $product){
print "{$product->name}:processing \n";
foreach ($this->callbacks as $callback){
call_user_func($callback,$product);
}
}
}
//create_function 创建匿名函数,回调的时候使用
$logger = create_function(
'$project',
'print "logging({$project->name})\n";'
);
/**
* 执行流程
* 实例化一个销售处理类,用注册回掉registerCallback的方法接收回调函数
* 使用sale方法接收product实例化的类,此类自动调用输出名字$name
* call_user_func函数使用匿名中的函数,输入name
*/
$processor = new ProcessSale();
$processor->registerCallback($logger);
$processor->sale(new product("shoes",6));
echo "
";
// $processor->sale(new product("coffee",6));
较为简洁的回调方式
新语法创建一个Mailer类,其中只有一个方法doMail,这个方法用于接收$product对象作为参数并且输出关于一天他的消息。
在调用registerCallback时传入类一个数组作为参数,这个数组第一个元素是Mailer对象,第二个元素是要调用的方法的名字的字符串。
include "base.php";
/**
* Class Mailer
*/
class Mailer{
public function doMail(product $product)
{
print "mailing ({$product->name})\n";//输出销售记录,编写这个类,就可以在让访问ProcessSale类的时候,进行一个和上下代码不相关的逻辑。
}
}
$processor = new ProcessSale();
$processor->registerCallback([new Mailer(),"doMail"]);//回调函数
print "\n";
$processor->sale(new product("coffee",6));
余下还有,需要再补