php 闭包函数 instanceof Closure

11 篇文章 0 订阅

instanceof 作用:(1)判断一个对象是否是某个类的实例(2)判断一个对象是否实现了某个接口。

PHP 闭包实现主要就是靠匿名函数

匿名函数,也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值。当然也有其它应用的情况。

动态调用静态类的时候

<?php

class test

{

    public static function getinfo()

    {

        var_dump(func_get_args());

    }

}

call_user_func(array('test', 'getinfo'), 'hello world');

输出 hello world

PHP的闭包就是依赖于匿名函数
1. 声明一个匿名函数
$func = function(){
    
}
2. 使用匿名函数
$func = function($param){
    echo $param;
}
$func ('调用匿名函数');

输出:调用匿名函数

将匿名函数在普通函数中当做参数传入,也可以被返回,这就是实现了一个简单的闭包

通俗的说: 子函数可以使用父函数中的局部变量,这种行为就叫做闭包

闭包的两个特点

  1. 作为一个函数变量的一个引用。当函数返回时,其处于激活状态
  2. 一个闭包就是当一个函数返回时,一个没有释放资源的栈区

其实上面两个点可以合成一个点,就是闭包函数返回时,该函数内部变量处于激活状态,函数所在栈区依然保留

function后面的括号相当于函数的用法,每次调用函数时传入数据一样,每次都需要传入,后面的use表示实例一次后不变,所有obj随时改变
闭包中的用法 匿名函数传参($obj)

function ($obj) use($param){}

use 的关键字使用(连接)了外部变量
如果没有&的符号,说明地址没有传进来,

function demo(){ 
	$a = 20;
	$b = 10;
	#如果没有&的符号,说明地址没有传进来,
	$one = function($str) use ($a, $b) {
		echo $str."<br>";
		echo $a."<br>";
		$a++;
		echo $b."<br>";
	};
	//调用了这个函数,$str输出hello world 
	$one('hello world');
	echo "..........".$a."-------<br>";
}
demo();

输出的值

hello world
21
10
-----------------20--------------
如果用了& 	$oen = function($str) use (&$a, &$b) {

输出的值

hello world
21
10
-----------------21--------------
function demo(){ 
	$a = 20;
	$b = 10;
	$one = function($str) use (&$a, &$b) {
		echo $str."<br>";
		echo $a."<br>";
		$a++;
		echo $b."<br>";
		#不能return 可能会停止的
		#return 
	};
	return $one;
}
$var = demo();
$var("sdfsdf");

sdfsdf
20
10

$a 是demo局部变量 ,调用一次释放一次 ,要是使用了闭包,就能保护这个变量,只能在这一个内部去用 ,外面访问a和b访问不了。

function demo($fun){
#相当于调用test
	echo $fun();
}
function test() {
	return "################";
}
demo("test");
echo "\n";
echo test();

echo test(); 能不能直接调用呢
回调函数,直接把匿名函数当参数传进来

输出:
################
################

function demo($fun){
	echo $fun();
}
#调用demo匿名函数参数传进来
demo(function(){
	return "02222222222222222222222<br>";
});

demo(function(){
		return "########################";
});

输出
02222222222222222222222
########################

function fullName($first_name ,$last_name,$callback){
	return $callback($first_name ,$last_name);
}

#匿名函数当参数传递进去,以回调函数的方式处理业务逻辑
fullName('Lebron','James',function($first_name ,$last_name){
		return $first_name . '' . $last_name;
});

echo $full_name

输出 

	Lebron James

闭包的三种方式

在函数里定义一个匿名函数,并且调用它

//闭包
function printStr($name) {//函数调用
    $func = function( $str ) use ($name) {
        echo $str.$name;
    };
    $func( 'some string' );
}
printStr('Clay');//函数调用

在这里插入图片描述

在函数中把匿名函数返回,并且调用它

//例二
//在函数中把匿名函数返回,并且调用它
function getPrintStrFunc() {
    $func = function( $str ) {
        echo $str;
    };
    return $func;
}
$printStrFunc = getPrintStrFunc();
$printStrFunc( 'some string' );

在这里插入图片描述

function enclosePerson($name)
{
	//把匿名函数返回
    return function ($doCommand) use ($name) {

    	var_dump($name);
    	var_dump($doCommand);

    	//把输出内容返回
        return sprintf('%s, %s', $name, $doCommand);
    };
}
//返回一个匿名函数 
$clay = enclosePerson('Clay');

#var_dump($clay('get me sweet tea!'));exit;

#调用匿名函数 
echo $clay('get me sweet tea!');

在这里插入图片描述

把匿名函数当做参数传递,并且调用它

function callFunc( $func ) {
    $func( 'som11e string' );
}
$printStrFunc = function( $str ) {
    echo $str;
};
callFunc( $printStrFunc );
//也可以直接将匿名函数进行传递。如果你了解js,这种写法可能会很熟悉
// callFunc( function( $str ) {
//     echo $str;
// } );

在这里插入图片描述

循环里面写闭包这种方法不是很好用,相当于每次都实例

function后面的()为可变变量,use()里面的变量为实例一次后不改动的变量,循环里面写闭包这种方法不是很好用,相当于每次都实例,所以闭包的写法可以先定义一个方法在调用

$arr = [
	'米' => ['咸粥','甜粥','米饭'],
	'面' => ['面条','画卷','馒头'],
];

$parm = '';
//parm 外部的引用的变量 所以是空的
$bag = function($data) use ($parm){
	// var_dump($data);exit;
	// var_dump($parm);
	$l = count($data);
	return $data[rand(0,$l-1)];
};

$eat_arr =[];

foreach($arr as $key=> $value)
{
	$each_arr [] = '吃'.$key.':'.$bag($value);
}

echo implode(',',$each_arr);
在这里插入代码片

在这里插入图片描述

$input = array(1, 2, 3, 4, 5, 6);
 
// 创建一个新的匿名函数然后赋值给一个变量
$filter_even = function($item) {
    return ($item % 2) == 0;
};
 
// 内建函数 array_filter 接收数据和函数
$output = array_filter($input, $filter_even);
print_r($output);
  
// 函数不一定要被赋值到变量,下面这一也是可以的:
$output = array_filter($input, function($item) {
    return ($item % 2) == 0;
});
print_r($output);

在这里插入图片描述

/**
 - 创建一个匿名过滤函数,只接收大于$min 的数
 *
 - 在“大于n”的过滤器之外返回单个过滤器
 */
function criteria_greater_than($min)
{
    return function($item) use ($min) {
        return $item > $min;
    };
}
 
$input = array(1, 2, 3, 4, 5, 6);
 
// 在input数组中使用已选的过滤函数来调用array_filter函数
$output = array_filter($input, criteria_greater_than(3));
 
print_r($output); // 大于3的元素

在这里插入图片描述

Closure

提到闭包就不得不想起匿名函数,也叫闭包函数(closures),貌似PHP闭包实现主要就是靠它。声明一个匿名函数是这样:

//匿名函数使用方式

$func = function() {
	echo "This is";
}; //带结束符

//通过变量来调用 
$func();

上面摘出来,代表闭包对象

function() {
	echo "This is";
};

$func 如果是实例打印出来是个1

echo $func instanceof Closure 

可以看到,匿名函数因为没有名字,如果要使用它,需要将其返回给一个变量。匿名函数也像普通函数一样可以声明参数,调用方法也相同:

$func = function( $param ) {

echo $param;

};

$func( 'some string' );

//输出:

//some string

顺便提一下,PHP在引入闭包之前,也有一个可以创建匿名函数的函数:create function,但是代码逻辑只能写成字符串,这样看起来很晦涩并且不好维护,所以很少有人用。

实现闭包

将匿名函数在普通函数中当做参数传入,也可以被返回。这就实现了一个简单的闭包。

下面请看例子

//例一

//在函数里定义一个匿名函数,并且调用它

function printStr() {

    $func = function( $str ) {

        echo $str;

    };

    $func( 'some string' );

}

printStr();

输出: some string
//例三

//把匿名函数当做参数传递,并且调用它

function callFunc( $func ) {

    $func( 'some string' );

}

$printStrFunc = function( $str ) {

    echo $str;

};

// print_r(callFunc( $printStrFunc ));

// //也可以直接将匿名函数进行传递。如果你了解js,这种写法可能会很熟悉

callFunc( function( $str ) {

    echo $str;

} );

输出some string

连接闭包和外界变量的关键字:USE

闭包可以保存所在代码块上下文的一些变量和值。PHP在默认情况下,匿名函数不能调用所在代码块的上下文变量,而需要通过使用use关键字。

function getMoney() {

    $rmb = 1;

    $dollar = 6;

    $func = function() use ( $rmb ) {

        echo $rmb;

        echo $dollar;

    };

    $func();

}

getMoney();

//输出:

//1

//报错,找不到dorllar变量

可以看到,dollar没有在use关键字中声明,在这个匿名函数里也就不能获取到它,所以开发中要注意这个问题。

有人可能会想到,是否可以在匿名函数中改变上下文的变量,但我发现是不可以的:

function getMoney() {

    $rmb = 1;

    $func = function() use ( $rmb ) {

        echo $rmb;

        //把$rmb的值加1

        $rmb++;

    };

    $func();

    echo $rmb;

}

getMoney();

//输出:

//1

//1

啊,原来use所引用的也只不过是变量的一个副本而已。但是我想要完全引用变量,而不是复制。

要达到这种效果,其实在变量前加一个 & 符号就可以了:

function getMoneyFunc() {

    $rmb = 1;

    $func = function() use ( &$rmb ) {

        echo $rmb;

        //把$rmb的值加1

        $rmb++;

    };

    return $func;

}

$getMoney = getMoneyFunc();

$getMoney();

$getMoney();

$getMoney();

//输出:

//1

//2

//3

PHP之道–函数式编程(译)
Laravel路由中间件的实现原理
array_reduce与闭包嵌套
php闭包函数(Closure)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟伟哦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值