【问题标题】:Using `$this` in an anonymous function in PHP pre 5.4.0在 PHP 5.4.0 之前的匿名函数中使用 `$this`
【发布时间】:2012-01-13 12:50:13
【问题描述】:

PHP 手册说明

在 PHP 之前不能在匿名函数中使用 $this 5.4.0

anonymous functions page 上。但我发现我可以通过将$this 分配给一个变量并将该变量传递给函数定义处的use 语句来使其工作。

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

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

【问题讨论】:

  • 只是一个小型论坛约定 - 通常接受答案比编辑问题以反映您的首选答案更好。主要是为了让回答永远有意义,但当然也要归功于正确的答案。
  • 请注意 $CI = $this;$CI =& $this; 并不实际上相同。也许出于您的目的,但它们不一样。试试$CI = 'bla'; var_dump($this); 和两个版本看看有什么不同。
  • @Rudie 我正在添加documentation 以供您发表评论
  • @steampowered 网上有一个很好的例子/文章,但我找不到它=) 抱​​歉。如果您没有看到差异,请尝试一下。这很明显。

标签: php anonymous-function


【解决方案1】:

当您尝试对其调用受保护或私有方法时,它将失败,因为以这种方式使用它算作从外部调用。据我所知,在 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"

更重要的是,您将能够更改 $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"

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

【讨论】:

  • 标记您的答案正确,但只是为了向其他读者澄清:问题中使用的约定适用于使用引用 $this 的对象的公共方法。
  • Non-public methods 可以使用反射访问。效率低下而且有点邪恶,但它确实有效。
【解决方案2】:

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

你的例子:

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

应该是:

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

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • OP 必须使用 5.3 或更高版本,因为 4.x 不支持匿名函数 :-)
      【解决方案5】:

      这很好。我认为你也可以这样做:

      $CI = $this;
      

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

      【讨论】:

        猜你喜欢
        • 2013-06-22
        • 2012-03-22
        • 2020-07-30
        • 1970-01-01
        • 1970-01-01
        • 2014-09-11
        • 2013-09-12
        • 2014-11-08
        • 2012-01-08
        相关资源
        最近更新 更多