道者编程

PHP的匿名函数和闭包

一:匿名函数

1:匿名函数就是没有名字的函数

<?php
$id = 100;
$name = function($str) use($id){ //use可以引入外部变量,这里把$id传进来,如果不需要外部变量,则不加use
	return $str.$id;
}; //匿名函数要带结束符

echo $name('lijie');
 

2:preg_replace_callback和匿名函数结合

<?php
//这是一个正则,把$string 里的int 找出来加10,替换
$string = "Some numbers: one: 1; two: 2; three: 3 end";
$ten = 10;
$newstring = preg_replace_callback(
    '/(\\d+)/',
    function($match) use ($ten) {return (($match[0] + $ten)); }, //$match为每次匹配得到的数据
    $string //原数据,从这里匹配
    );
echo $newstring; 

//这里为什么要用匿名函数有两个原因
//1:没必要单独为preg_replace_callback命令一个函数
//2:如果有外部变量,可以通过use传值

3:再看一个回调函数中的使用:

<?php

$arr = ['1'=>'t1','2'=>'t2','3'=>'t3'];

$new = array_map(function($v){
    return $v.' - abc';
},$arr); //通过匿名函数回调,这里$arr数组有三个元素,回调三次;当然也可以通过foreach实现

print_r($new);
 如果不用匿名函数,则传统的写法:

<?php

$arr = ['1'=>'t1','2'=>'t2','3'=>'t3'];
$new = array_map("cube", $arr);
//如果不通过匿名函数,则下面这种写法
function cube($str)
{
	return $v.' - abc';
}
print_r($new);
 

二:闭包

函数中包含子函数,子函数继承父函数的变量,这就是闭包,子函数调用父函数的局部变量用关键字 use

以下例子:将匿名函数在普通函数中当做参数传入,也可以被返回。

<?php
function add($a) //普通函数add
 { 
 	$abAdd = function ($b=2) use($a) { //匿名函数,如果不加use,匿名函数无法调用add函数中的变量
 		return $a+$b;  //如果不加use,这里就无法调取$a
 	}; 
	return $abAdd; //返回这个匿名函数
}

$abAdd = add(21); //这里add是返回的一个对象
echo $abAdd(6);//调用匿名函数

上面功能好像没什么吸引力,再看一个例子,一个简单的容器:

<?php
class Di
{
    private $factory;
 
    public function set($id, $value)
    {
        $this->factory[$id] = $value;
    }
 
    public function get($id)
    {
        $val = $this->factory[$id];
        return $val();//如果不加括号,仅仅返回的是闭包类,并不是User实例
    }
}
 
class User
{
    private $username;
 
    public function __construct($username = '')
    {
        $this->username = $username;
    }
 
    public function getUserName()
    {
        return $this->username;
    }
}
 
$di = new Di();
 
// 注册,在此使用了闭包,所以实际上并不会实例化User类,只有在后面get的时候才会实例化
$di->set('a', function(){
    return new User('张三');
});
$a = $di->get('a'); //获取服务,相当于实例化
echo $a->getUserName();
Di容器用来保存对象实例,set()方法注册到容器,然后通过get获取,set的时候不会真的实例化,只有在get的时候才实例化,这样实现了按需加载,而通过容器也便于统一管理。


最新评论:
1楼 广东省深圳市 电信 发表于 2018-05-08 17:09:09
5.3最重要的变动就是匿名函数和命名空间了
共有 1 条记录  首页 上一页 下一页 尾页 1
我要评论:

看不清楚