欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

Closure 类 有大用

Closure 类

(PHP 5 >= 5.3.0, PHP 7)

简介

用于代表 匿名函数 的类.

匿名函数(在 PHP 5.3 中被引入)会产生这个类型的对象。在过去,这个类被认为是一个实现细节,但现在可以依赖它做一些事情。自 PHP 5.4 起,这个类带有一些方法,允许在匿名函数创建后对其进行更多的控制。

除了此处列出的方法,还有一个 __invoke 方法。这是为了与其他实现了 __invoke()魔术方法 的对象保持一致性,但调用匿名函数的过程与它无关。

类摘要

Closure {
/* 方法 */
__construct ( void )
public static bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] ) : Closure
public bindTo ( object $newthis [, mixed $newscope = 'static' ] ) : Closure
}

Table of Contents

add a note add a note

User Contributed Notes 3 notes

chuck at bajax dot us ¶
4 years ago
This caused me some confusion a while back when I was still learning what closures were and how to use them, but what is referred to as a closure in PHP isn't the same thing as what they call closures in other languages (E.G. JavaScript).

In JavaScript, a closure can be thought of as a scope, when you define a function, it silently inherits the scope it's defined in, which is called its closure, and it retains that no matter where it's used.  It's possible for multiple functions to share the same closure, and they can have access to multiple closures as long as they are within their accessible scope.

In PHP,  a closure is a callable class, to which you've bound your parameters manually.

It's a slight distinction but one I feel bears mentioning.
joe dot scylla at gmail dot com ¶
3 years ago
Small little trick. You can use a closures in itself via reference.

Example to delete a directory with all subdirectories and files:

<?php
$deleteDirectory 
null;
$deleteDirectory = function($path) use (&$deleteDirectory) {
    
$resource opendir($path);
    while ((
$item readdir($resource)) !== false) {
        if (
$item !== "." && $item !== "..") {
            if (
is_dir($path "/" $item)) {
                
$deleteDirectory($path "/" $item);
            } else {
                
unlink($path "/" $item);
            }
        }
    }
    
closedir($resource);
    
rmdir($path);
};
$deleteDirectory("path/to/directoy");
?>
luk4z_7 at hotmail dot com ¶
4 years ago
Scope
A closure encapsulates its scope, meaning that it has no access to the scope in which it is defined or executed. It is, however, possible to inherit variables from the parent scope (where the closure is defined) into the closure with the use keyword:

function createGreeter($who) {
              return function() use ($who) {
                  echo "Hello $who";
              };
}

$greeter = createGreeter("World");
$greeter(); // Hello World

This inherits the variables by-value, that is, a copy is made available inside the closure using its original name.
font: Zend Certification Study Guide.

来自 https://www.php.net/manual/zh/class.closure.php




php闭包函数(Closure)

96 
爱学习的小仙女呀 
2018.05.15 14:36 字数 801 阅读 1632评论 0

匿名函数

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

代码如下:

$func = function() {

}; //带结束符

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

代码如下:

$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闭包的特性并没有太大惊喜,其实用CLASS就可以实现类似甚至强大得多的功能,更不能和js的闭包相提并论,只能期待PHP以后对闭包支持的改进。不过匿名函数还是挺有用的,比如在使用preg_replace_callback等之类的函数可以不用在外部声明回调函数了。

来自  https://www.jianshu.com/p/c88d5bb329b4

普通分类: