资讯专栏INFORMATION COLUMN

PHP新特性之闭包、匿名函数

luzhuqun / 742人阅读

摘要:闭包闭包是什么闭包和匿名函数在中被引入。可以将匿名函数和闭包视作相同的概念。闭包和字符串或整数一样,是一等值类型。何时使用我们通常把闭包当做函数和方法的回调使用。

闭包
闭包是什么?

1).闭包和匿名函数在PHP5.3中被引入。
2).闭包是指在创建时封装函数周围状态的函数,即使闭包所在的环境不存在了,闭包封装的状态依然存在,这一点和Javascript的闭包特性很相似。
3).匿名函数就是没有名称的函数,匿名函数可以赋值给变量,还可以像其他任何PHP对象一样传递。可以将匿名函数和闭包视作相同的概念。
4).需要注意的是闭包使用的语法和普通函数相同,但是他其实是伪装成函数的对象,是Closure类的实例。闭包和字符串或整数一样,是一等值类型。

创建闭包
$closure = function ($name) {
  return sprintf("hello %s", $name);
};

echo $closure("Josh");

我们之所以可以调用$closure变量,是因为这个变量的值是一个闭包,而且闭包对象实现了__invoke()魔术方法,只要后面跟着(),PHP就会查找__invoke()方法。这里简单解释下这个魔术方法:

class testClass
{
    public function __invoke
    {
        print "hello world";
    }
}
$n = new testClass;
$n();

PHP自从5.3版以来就新增了一个叫做__invoke()的魔术方法,使用该方法就可以在创建实例后,直接调用对象。

何时使用?

我们通常把PHP闭包当做函数和方法的回调使用。很多PHP函数都会用到回调函数,例如array_map()preg_replace_callback()

$numbersPlusOne = array_map(function($number) {
    return $number + 1;
}, [1, 2, 3]);
如何理解附加状态?

1).注意PHP闭包不会真的像JS一样自动封装应用的状态,在PHP中必须调用闭包对象的bindTo方法或者使用use关键字,把状态附加到PHP闭包上。来看一个例子

function enclosePerson($name)
{
    return function ($doCommand) use ($name) {
        return sprintf("%s , %s", $name, $doCommand);
   };
}
//把字符串“Clay”封装在闭包中
$clay = enclosePerson("Clay");
//传入参数,调用闭包
echo $clay("get me sweat tea!"); // Clay, get me sweat tea!

在这个例子中,函数enclosePerson()有一个$name参数,这个函数返回一个闭包对象,这个闭包封装了$name参数,即便返回的对象跳出了enclosePerson()函数的作用域,它也会记住$name参数的值,因为$name变量仍然在闭包中。
2).使用use关键字可以把多个关键字传入闭包,此时要想像PHP函数或方法的参数一样,使用逗号分割多个参数。
3).PHP闭包仍然是对象,可以使用$this关键字获取闭包的内部状态。闭包的默认状态里面有一个__invoke()魔术方法和bindTo()方法。
4).bindTo()方法为闭包增加了一些有趣的东西。我们可以使用这个方法把Closure对象内部状态绑定到其他对象上。bindTo()方法的第二个参数可以指定绑定闭包的那个对象所属的PHP类,这样我们就可以访问这个类的受保护和私有的成员变量。看下面的代码示例:

class App
{
    protected $route = array();
    protected $responseStatus = "200 OK";
    protected $responseContentType = "text/html";
    protected $responseBody = "Hello world";

    public function addRoute($routePath, $routeCallback)
    {
        $this->routes[$routePath] = $routeCallback->bindTo($this, __CLASS__);
    }

    public function dispatch($currentPath)
    {
        foreach($this->routes as $routePath => $callback) {
            if ($routePath === $currentPath) {
                 $callback();
            }
        }
        header("HTTP/1.1" . $this->responseStatus);
        header("Content-type: " . $this->responseContentType);
        header("Content-length: " . mb_strlen($this->responseBody));
        echo $this->responseBody;
    }
}

我们把路由回调绑定到了当前的App实例上,这样就可以在回调函数中处理App实例的状态了。

$app = new App();
$app->addRoute("/users/xiaoxiao", function () {
    $this->responseContentType = "application/json;charset=utf8";
    $this->responseBody = "{"name" : "xiaoxiao"}";
});
$app->dispatch("/users/xiaoxiao");
专题系列

PHP专题系列目录地址:https://github.com/xx19941215/webBlog
PHP专题系列预计写二十篇左右,主要总结我们日常PHP开发中容易忽略的基础知识和现代PHP开发中关于规范、部署、优化的一些实战性建议,同时还有对Javascript语言特点的深入研究。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/23304.html

相关文章

  • PHP 闭包那些事儿

    摘要:注理论上讲闭包和匿名函数是不同的概念,不过将其视作相同的概念。匿名函数可以从父作用域继承变量,而这个父作用域是定义该闭包的函数不一定是调用它的函数。 匿名函数 匿名函数,也叫闭包函数,说白了就是没有名字的函数,和一般函数结构一样,只是少了函数名以及最后需要加上分号;。 注:理论上讲闭包和匿名函数是不同的概念,不过PHP将其视作相同的概念。 $func = function() { ...

    winterdawn 评论0 收藏0
  • PHP匿名函数和JS匿名函数

    摘要:新添加一个新特性官方文档,想用闭包模拟一下,然后发现和闭包的差别结果会不一样结果截图左边是结果,右边是结果两边很明显和在闭包的变量的处理有差异再匿名函数变量加上引用符号,然后结果就是一样的了 php5.5新添加一个新特性 yeild 官方文档,想用闭包模拟一下yeild,然后发现JS和PHP闭包的差别 function js_shell(){ var a...

    MycLambert 评论0 收藏0
  • PHP匿名函数和JS匿名函数

    摘要:新添加一个新特性官方文档,想用闭包模拟一下,然后发现和闭包的差别结果会不一样结果截图左边是结果,右边是结果两边很明显和在闭包的变量的处理有差异再匿名函数变量加上引用符号,然后结果就是一样的了 php5.5新添加一个新特性 yeild 官方文档,想用闭包模拟一下yeild,然后发现JS和PHP闭包的差别 function js_shell(){ var a...

    AaronYuan 评论0 收藏0
  • PHP闭包(Closure)初探

    摘要:实现闭包将匿名函数在普通函数中当做参数传入,也可以被返回。如果将匿名函数返回给外界,匿名函数会保存所引用的变量,而外界则不能得到这些变量,这样形成闭包这个概念可能会更清晰一些。 原文:http://my.oschina.net/melonol/blog/126694 匿名函数提到闭包就不得不想起匿名函数,也叫闭包函数(closures),貌似PHP闭包实现主要就是靠它。声明一个匿名函数...

    roadtogeek 评论0 收藏0
  • PHP7特性小结

    摘要:标量类型声明在中,引入了一个新的特性,即标量类型声明。弃用样式构造函数是与它们定义的类具有相同名称的方法,现在已被弃用,并且将来将被删除。 showImg(https://segmentfault.com/img/remote/1460000012438557?w=1024&h=456); 说明 PHP 7使用新的Zend Engine 3.0将应用程序性能提高近两倍,内存消耗比PHP...

    Steven 评论0 收藏0

发表评论

0条评论

luzhuqun

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<