PHP中的闭包function() use() {}使用场景和技巧
时间:2023-06-09 21:54:07
由于存在函数内部不能访问全局作用的,所以就需要一种可以引入上一级作用域的语法结构,可以通过use使用函数声明时所在作用域的变量的值。php的闭包可能不常用,但是在某些场合之下还是可以考虑用php的闭包来实现某些功能的。
php的闭包(Closure)也就是匿名函数。是PHP5.3引入的。
提到闭包就不得不想起匿名函数,也叫闭包函数(closures)。匿名函数因为没有名字,如果要使用它,需要将其返回给一个变量。匿名函数也像普通函数一样可以声明参数,调用方法也相同。
$func = function( $param ) {
echo $param;
};
$func( 'some string' );
//输出:
//some string
function () use () {}语法结构
在PHP中,由于存在函数内部不能访问全局作用的,所以就需要一种可以引入上一级作用域的语法结构,和上级作用域产生了联系,语句结构如下:
function () use () {}
将需要引入到这个函数作用于内的变量写入到use的括号里面就可以了,举个例子
<?php
$a = 1;
$closure = function () use ($a) {
echo $a;
};
$closure();
?>
输出的结果为
1
闭包function() use() {}的使用场景:
1 减少foreach的循环的代码
<?php
// 一个基本的购物车,包括一些已经添加的商品和每种商品的数量。
// 其中有一个方法用来计算购物车中所有商品的总价格。该方法使用了一个closure作为回调函数。
class Cart
{
const PRICE_BUTTER = 1.00;
const PRICE_MILK = 3.00;
const PRICE_EGGS = 6.95;
protected $products =array();
public function add($product,$quantity)
{
$this->products[$product] = $quantity;
}
public function getQuantity($product)
{
return isset($this->products[$product]) ? $this->products[$product] :
FALSE;
}
public function getTotal($tax)
{
$total = 0.00;
$callback = function ($quantity,$product)use ($tax, &$total)
{
$pricePerItem = constant("::PRICE_" . strtoupper($product));
$total += ($pricePerItem *$quantity) * ($tax + 1.0);
};
array_walk($this->products,$callback);
return round($total, 2);;
}
}
$my_cart =new Cart;
// 往购物车里添加条目
$my_cart->add('butter', 1);
$my_cart->add('milk', 3);
$my_cart->add('eggs', 6);
// 打出出总价格,其中有 5% 的销售税.
print $my_cart->getTotal(0.05) . "\n";
// The result is 54.29
?>
这里如果我们改造getTotal函数必然要使用到foreach
2 减少函数的参数
function html ($code ,$id="",$class=""){
if ($id !=="")$id =" id = \"$id\"" ;
$class = ($class !=="")?" class =\"$class\"":">";
$open ="<$code$id$class";
$close ="</$code>";
return function ($inner ="")use ($open,$close){
return "$open$inner$close";};
}
如果是使用平时的方法,我们会把inner放到html函数参数中,这样不管是代码阅读还是使用都不如使用闭包
3 解除递归函数
<?php
$fib =function($n)use(&$fib) {
if($n == 0 || $n == 1) return 1;
return $fib($n - 1) + $fib($n - 2);
};
echo $fib(2) . "\n";// 2
$lie =$fib;
$fib =function(){die('error');};//rewrite $fib variable
echo $lie(5);// error because $fib is referenced by closure
注意上题中的use使用了&,这里不使用&会出现错误n-1)是找不到function的(前面没有定义fib的类型)
所以想使用闭包解除循环函数的时候就需要使用
<?php
$recursive =function ()use (&$recursive){
// The function is now available as $recursive
}
这样的形式
4 关于延迟绑定
如果你需要延迟绑定use里面的变量,你就需要使用引用,否则在定义的时候就会做一份拷贝放到use中
<?php
$result = 0;
$one =function(){
var_dump($result);
};
$two =function()use($result) {
var_dump($result);
};
$three =function()use (&$result) {
var_dump($result);
};
$result++;
$one(); // outputs NULL: $result is not in scope
$two(); // outputs int(0): $result was copied
$three(); // outputs int(1)
使用引用和不使用引用就代表了是调用时赋值,还是申明时候赋值
标签:php,闭包,use
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Linux Centos 下使用yum 命令安装mysql实现步骤
2024-01-28 02:24:42
python使用pygame实现笑脸乒乓球弹珠球游戏
2021-07-26 09:49:47
![](https://img.aspxhome.com/file/2023/3/87473_0s.jpg)
python+opencv边缘提取与各函数参数解析
2023-12-24 11:17:54
![](https://img.aspxhome.com/file/2023/7/124667_0s.png)
解决bootstrap导航栏navbar在IE8上存在缺陷的方法
2023-09-03 10:55:07
![](https://img.aspxhome.com/file/2023/0/56080_0s.gif)
SQL Server恢复模型之批量日志恢复模式
2024-01-28 07:34:22
![](https://img.aspxhome.com/file/2023/6/98036_0s.png)
Python 日期的转换及计算的具体使用详解
2023-01-06 11:31:27
用Asp+XmlHttp实现RssReader功能
2008-07-09 12:20:00
用Python读取几十万行文本数据
2023-10-13 21:56:04
SQLServer2005 没有日志文件(*.ldf) 只有数据文件(*.mdf) 恢复数据库的方法
2024-01-24 00:15:37
mysql中count(), group by, order by使用详解
2024-01-26 00:48:11
asp文章上一篇,下一篇实现代码
2008-03-24 20:15:00
Django学习笔记之Class-Based-View
2023-09-07 15:37:25
OpenCV实现车辆识别和运动目标检测
2023-09-22 18:55:40
![](https://img.aspxhome.com/file/2023/6/82606_0s.jpg)
Python中常用操作字符串的函数与方法总结
2023-07-25 12:09:23
mysql中判断记录是否存在方法比较
2024-01-27 05:14:49
分享python 写 csv 文件的两种方法
2023-04-07 07:03:47
![](https://img.aspxhome.com/file/2023/9/113149_0s.png)
ASP.net与SQLite数据库通过js和ashx交互(连接和操作)
2024-01-28 15:21:17
![](https://img.aspxhome.com/file/2023/6/93136_0s.png)
线程安全及Python中的GIL原理分析
2022-09-06 11:16:20
sql时间格式化输出、Convert函数应用示例
2024-01-22 01:23:53
XMLHttpRequest Level 2 使用指南
2024-04-18 10:49:50
![](https://img.aspxhome.com/file/2023/3/136483_0s.png)