【问题标题】:PHP Fatal error: Cannot use $this as parameterPHP 致命错误:不能使用 $this 作为参数
【发布时间】:2018-03-03 01:32:08
【问题描述】:

我有以下 PHP 方法,它是运行良好的代码库的一部分:

<?php
class HooksTest extends DrupalTestCase {
  public function testPageAlterIsLoggedIn() {
    $this->drupal->shouldReceive('userIsLoggedIn')
      ->once()
      ->andReturn(TRUE);
    $this->drupal->shouldReceive('drupalPageIsCacheable')
      ->once()
      ->andReturnUsing(function ($this) {
        return $this;
      });
    $page = [];
    $cacheable = $this->object->pageAlter($page);
    $this->assertFalse($cacheable);
  }
}

该代码之前通过了所有 CI 测试(使用 phpunit)。

但是现在当我通过php HooksTest.php 调用文件时,出现以下错误:

PHP 致命错误:无法在第 11 行的 HooksTest.php 中使用 $this 作为参数

致命错误:无法在第 11 行的 HooksTest.php 中使用 $this 作为参数

我已经测试过 PHP 7.1、7.2 和相同的问题。我相信它在 PHP 5.6 中工作。

如何将上面的代码转换为相同的含义?

从函数参数中删除$this就足够了吗?

【问题讨论】:

  • 使用 self:: 也许?
  • 我认为你不能将$this 传递给-&gt;andReturnUsing(function ($this) { 中的函数
  • 这是通过所有测试的现有代码的一部分,所以它不是我的发明。我知道它工作正常,现在在 PHP 7.x 下失败了。
  • 看起来问题是使用$this作为参数的名称会在参数和引用函数范围内的对象的$this之间产生冲突。
  • 看起来这是在 7.1 中实现的更改:wiki.php.net/rfc/this_var#disable_using_this_as_parameter

标签: php this fatal-error


【解决方案1】:

跳过$this参数,改变

function ($this) {
    return $this;
}

function () {
    return $this;
}

Anonymous functions页面上查看示例#5 $this的自动绑定

<?php
class Test
{
    public function testing()
    {
        return function() {
            var_dump($this);
        };
    }
}
$object = new Test;
$function = $object->testing();
$function();
?>

【讨论】:

    【解决方案2】:

    如果您希望它以与以前相同的方式工作,则不应将$this 作为参数删除。您应该将参数名称更改为其他名称,并在闭包中更改相应的变量名称。

    通过 PHP 5.6,在类方法的闭包中使用 $this 作为参数将掩盖引用父对象的 $this。例如:

    class Example
    {
        public function test ($param) {
            $closure = function ($whatever) {      // $this not used as parameter
                return $this;                      // $this refers to the Example object
            };
            return $closure($param);
        }
    
        public function test2 ($param) {
            $closure = function($this) {          // $this used as parameter
                return $this;                     // $this no longer refers to Example object
            };
            return $closure($param);
        }
    
    }
    
    $ex = new Example;
    $not_masked = $ex->test('foo');
    $masked = $ex->test2('foo');
    
    var_dump($not_masked, $masked);
    

    Working example on 3v4l.org

    在 PHP 5.6 中,$masked 将是字符串 'foo',不是 $ex 对象。

    根据您可以在 3v4l.org 链接上看到的不同版本的输出,从 7.0.0 到 7.0.6 有一段短暂的时期,其中 $this 参数显然会被忽略以支持对象自我参照。我假设他们不允许在以后的版本中使用 $this 作为参数,以避免 $this 在闭包范围中实际引用的内容不明确。

    看起来这只是在原始代码中混淆命名。为了使它像以前一样工作:

    ->andReturnUsing(function ($anyOtherName) {
        return $anyOtherName;
    });
    

    【讨论】:

      【解决方案3】:

      是的,正如 aynber 之前所说,您不能将 $this 作为函数参数传递。通过这样做,您基本上是在重新声明它。您应该将其作为函数参数删除。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多