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

2023-12-19 17:08
文章标签 函数 特性 php 匿名 之闭

本文主要是介绍PHP新特性之闭包、匿名函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

闭包
闭包是什么?

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

创建闭包
$closure = function () {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新特性之闭包、匿名函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/512999

相关文章

Python itertools中accumulate函数用法及使用运用详细讲解

《Pythonitertools中accumulate函数用法及使用运用详细讲解》:本文主要介绍Python的itertools库中的accumulate函数,该函数可以计算累积和或通过指定函数... 目录1.1前言:1.2定义:1.3衍生用法:1.3Leetcode的实际运用:总结 1.1前言:本文将详

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

MySQL数据库函数之JSON_EXTRACT示例代码

《MySQL数据库函数之JSON_EXTRACT示例代码》:本文主要介绍MySQL数据库函数之JSON_EXTRACT的相关资料,JSON_EXTRACT()函数用于从JSON文档中提取值,支持对... 目录前言基本语法路径表达式示例示例 1: 提取简单值示例 2: 提取嵌套值示例 3: 提取数组中的值注意

Java function函数式接口的使用方法与实例

《Javafunction函数式接口的使用方法与实例》:本文主要介绍Javafunction函数式接口的使用方法与实例,函数式接口如一支未完成的诗篇,用Lambda表达式作韵脚,将代码的机械美感... 目录引言-当代码遇见诗性一、函数式接口的生物学解构1.1 函数式接口的基因密码1.2 六大核心接口的形态学

五大特性引领创新! 深度操作系统 deepin 25 Preview预览版发布

《五大特性引领创新!深度操作系统deepin25Preview预览版发布》今日,深度操作系统正式推出deepin25Preview版本,该版本集成了五大核心特性:磐石系统、全新DDE、Tr... 深度操作系统今日发布了 deepin 25 Preview,新版本囊括五大特性:磐石系统、全新 DDE、Tree

Oracle的to_date()函数详解

《Oracle的to_date()函数详解》Oracle的to_date()函数用于日期格式转换,需要注意Oracle中不区分大小写的MM和mm格式代码,应使用mi代替分钟,此外,Oracle还支持毫... 目录oracle的to_date()函数一.在使用Oracle的to_date函数来做日期转换二.日

PHP执行php.exe -v命令报错的解决方案

《PHP执行php.exe-v命令报错的解决方案》:本文主要介绍PHP执行php.exe-v命令报错的解决方案,文中通过图文讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下... 目录执行phpandroid.exe -v命令报错解决方案执行php.exe -v命令报错-PHP War

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

C++操作符重载实例(独立函数)

C++操作符重载实例,我们把坐标值CVector的加法进行重载,计算c3=c1+c2时,也就是计算x3=x1+x2,y3=y1+y2,今天我们以独立函数的方式重载操作符+(加号),以下是C++代码: c1802.cpp源代码: D:\YcjWork\CppTour>vim c1802.cpp #include <iostream>using namespace std;/*** 以独立函数