php 闭包函数 instanceof Closure

  • 动态调用静态类的时候
  • 闭包的三种方式
    • 在函数里定义一个匿名函数,并且调用它
    • 在函数中把匿名函数返回,并且调用它
    • 把匿名函数当做参数传递,并且调用它
  • 循环里面写闭包这种方法不是很好用,相当于每次都实例
  • 实现闭包

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

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

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

动态调用静态类的时候

<?phpclass 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){#相当于调用testecho $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)

php 闭包函数 instanceof Closure相关推荐

  1. ES6/04/严格模式,开启严格模式,严格模式与普通模式对比发生了那些变化,高阶函数,闭包函数,递归函数,递归实例(1,阶乘,2,斐波那契数列,3,根据id返回对应数据对象),浅拷贝和深拷贝

    函数 开启严格模式 1,用 " use strict"; 语句为整个脚本(即:script标签)开启严格模式;在<script>标记的第一行写上"use st ...

  2. php的匿名函数和闭包函数

    php的匿名函数和闭包函数 tags: 匿名函数 闭包函数 php闭包函数 php匿名函数 function use 引言:匿名函数和闭包函数都不是特别高深的知识,但是很多刚入门的朋友却总是很困惑,因 ...

  3. php的闭包函数bingto_PHP 闭包那点事儿

    匿名函数 匿名函数,也叫闭包函数,说白了就是"没有名字的函数",和一般函数结构一样,只是少了函数名以及最后需要加上分号;. 注:理论上讲闭包和匿名函数是不同的概念,不过PHP将其视 ...

  4. python中msg函数_Python 中闭包函数和装饰器

    一.闭包函数的概述 闭包 closure, 是一种代码的组织结构.当一个内嵌函数引用其外部作用域的变量,就形成一个闭包函数.闭包函数有一个内嵌函数,内嵌函数引用外部函数中的变量,外部函数的返回值是内嵌 ...

  5. js 闭包函数 构造函数_JavaScript中的闭包,库里函数和酷抽象

    js 闭包函数 构造函数 In this article, we will talk about closures and curried functions and we'll play aroun ...

  6. 深入理解php 匿名函数和 Closure

    而在PHP 5.3发布的时候, 其中有一条new feature就是支持闭包/Lambda Function, 我第一反应是以为zval新增了一个IS_FUNCTION, 但实际上是构造了一个PHP ...

  7. php里面用魔术方法和匿名函数闭包函数动态的给类里面添加方法

    1.认识  __set  (在给不可访问属性赋值时,__set() 会被调用) 也就是说你再访问一个类里面没有的属性,会出发这个方法 class A{private $aa = '11';public ...

  8. python闭包的应用场景_Python闭包函数定义与用法分析

    python函数的闭包怎么理解小编憎恨离别.但若,离别能让你牵挂,小编愿意离开你. 1. 闭包的概念 首先还得从基本概念说起,什么是闭包呢?来看下维基上的解释: 复制代码代码如下: 在计算机科学中,闭 ...

  9. php的闭包函数bingto_php的闭包

    闭包是指在创建时封装周围状态的函数,即使闭包所在的环境的不存在了,闭包中封装的状态依然存在. 匿名函数其实就是没有名称的函数,匿名函数可以赋值给变量,还能像其他任何PHP函数对象那样传递.不过匿名函数 ...

最新文章

  1. 差点败北!B站疯传3W次,堪称最强Java面试题,顺利拿下阿里P7的35K*16 薪 Offer...
  2. 抽奖啦!AI内参、李沐新书深度学习、米家扫地机器人送送送
  3. Java EE API整合:为什么Spring要与“笨重”的Java EE共舞?
  4. OpenGL渲染管线,着色器,光栅化等概念理解
  5. html5上传视频和预览,HTML5 上传前预览
  6. MSP430杂谈--IIC通信
  7. 基于C语言的软件,基于C语言的计算机软件编程分析
  8. 云莲MK8215_联芸MAS0902固态硬盘开卡教程,量产工具软件下载
  9. android信鸽推送通知栏,【信鸽推送】点击推送通知后,默认会从程序Launcher进入,返回时会回到主界面的问题...
  10. 测试php连接mysql的实例实现
  11. 程序员该如何对付日常小病小痛?
  12. 天津大学计算机系分数线,2019天津大学录取分数线及历年专业分数线统计表【文科 理科】...
  13. 方法finalize()的应用
  14. “杜拉拉升职记”电影看后感
  15. Wavefront公司的.obj文件格式及.mtl文件格式
  16. 怎么把电脑上的文件备份到百度网盘?
  17. CSS表格与浮动定位
  18. 大数据和传统数据的区别
  19. Pycharm的快捷键
  20. 泰斗T302模块选择导航系统方法

热门文章

  1. 印象笔记与有道云笔记的优缺点比较表格
  2. 操作系统原理 —— 操作系统的四个特征:并发、共享、虚拟、异步 (二)
  3. uni-app 父组件调用子组件方法
  4. 物联网工程实训第七天
  5. oracle多个innerjoin,SQL语句多表inner join的用法
  6. 微信小程序picker-view自动回滚
  7. 天气变冷了,给你的爱人制作一个天气提醒小助手
  8. 计算机在线考试系统,高效刷题考试平台!
  9. 一辈子简单做人,平平淡淡过人生
  10. MongoDB查询性能分析