在 PHP 5.4.0 之前的匿名函数中使用 `$this`

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8391099/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 04:36:14  来源:igfitidea点击:

Using `$this` in an anonymous function in PHP pre 5.4.0

phpanonymous-function

提问by steampowered

The PHP manual states

PHP 手册指出

It is not possible to use $thisfrom anonymous function before PHP 5.4.0

$thisPHP 5.4.0 之前的匿名函数无法使用

on the anonymous functions page. But I have found I can make it work by assigning $thisto a variable and passing the variable to a usestatement at the function definition.

匿名函数页面上。但是我发现我可以通过分配$this给变量并将变量传递给use函数定义中的语句来使其工作。

$CI = $this;
$callback = function () use ($CI) {
    $CI->public_method();
};

Is this a good practice?
Is there a better way to access $thisinside an anonymous function using PHP 5.3?

这是一个好习惯吗?
有没有更好的方法来$this使用 PHP 5.3访问匿名函数?

采纳答案by K. Norbert

It will fail when you try to call a protected or private method on it, because using it that way counts as calling from the outside. There is no way to work around this in 5.3 as far as I know, but come PHP 5.4, it will work as expected, out of the box:

当您尝试对其调用受保护或私有方法时,它将失败,因为以这种方式使用它算作从外部调用。据我所知,在 5.3 中没有办法解决这个问题,但是到了 PHP 5.4,它将按预期工作,开箱即用:

class Hello {

    private $message = "Hello world\n";

    public function createClosure() {
        return function() {
            echo $this->message;
        };
    }

}
$hello = new Hello();
$helloPrinter = $hello->createClosure();
$helloPrinter(); // outputs "Hello world"

Even more, you will be able to change what $this points to at runtime, for anonymus functions (closure rebinding):

更重要的是,对于匿名函数(闭包重新绑定),您将能够在运行时更改 $this 指向的内容:

class Hello {

    private $message = "Hello world\n";

    public function createClosure() {
        return function() {
            echo $this->message;
        };
    }

}

class Bye {

    private $message = "Bye world\n";

}

$hello = new Hello();
$helloPrinter = $hello->createClosure();

$bye = new Bye();
$byePrinter = $helloPrinter->bindTo($bye, $bye);
$byePrinter(); // outputs "Bye world"

Effectively, anonymus functions will have a bindTo() method, where the first parameter can be used to specify what $this points to, and the second parameter controls what should the visibility level be. If you omit the second parameter, the visibility will be like calling from the "outside", eg. only public properties can be accessed. Also make note of the way bindTo works, it does not modify the original function, it returns a new one.

实际上,匿名函数将有一个bindTo() 方法,其中第一个参数可用于指定 $this 指向的内容,第二个参数控制可见性级别应该是什么。如果省略第二个参数,可见性将类似于从“外部”调用,例如。只能访问公共属性。还要注意 bindTo 的工作方式,它不会修改原始函数,而是返回一个新函数。

回答by Christof Coetzee

Don't always rely on PHP to pass objects by reference, when you are assigning a reference itself, the behavior is not the same as in most OO languages where the original pointer is modified.

不要总是依赖 PHP 通过引用传递对象,当您分配引用本身时,行为与修改原始指针的大多数 OO 语言中的行为不同。

your example:

你的例子:

$CI = $this;
$callback = function () use ($CI) {
$CI->public_method();
};

should be:

应该:

$CI = $this;
$callback = function () use (&$CI) {
$CI->public_method();
};

NOTE THE REFERENCE "&" and $CI should be assigned after final calls on it has been done, again else you might have unpredictable output, in PHP accessing a reference is not always the same as accessing the original class - if that makes sense.

注意 REFERENCE "&" 和 $CI 应该在对它的最终调用完成后分配,否则你可能会有不可预测的输出,在 PHP 中访问引用并不总是与访问原始类相同 - 如果这是有道理的。

http://php.net/manual/en/language.references.pass.php

http://php.net/manual/en/language.references.pass.php

回答by Itay Moav -Malimovka

That is the normal way it was done.
b.t.w, try to remove the &it should work without this, as objects pass by ref any way.

这是正常的做法。
顺便说一句,尝试删除&它应该在没有这个的情况下工作,因为对象以任何方式通过引用。

回答by fire

That seems alright if your passing by reference it's the correct way to do it. If your using PHP 5 you don't need the &symbol before $thisas it will always pass by reference regardless.

如果您通过引用传递它是正确的方法,那似乎没问题。如果您使用 PHP 5,则&之前不需要该符号,$this因为无论如何它都会通过引用传递。

回答by halfer

This is fine. I should think you could do this also:

这可以。我应该认为你也可以这样做:

$CI = $this;

... since assignations involving objects will always copy references, not whole objects.

...因为涉及对象的赋值将始终复制引用,而不是整个对象。