PHP致命错误:不能使用$ this作为参数

时间:2017-09-21 15:52:15

标签: php this fatal-error

我有以下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行的$this中使用 HooksTest.php 作为参数

     

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

我已经使用PHP 7.1,7.2和同样的问题进行了测试。我相信它在PHP 5.6中工作。

如何将上述代码转换为具有相同含义?

从函数参数中删除$this是否足够?

3 个答案:

答案 0 :(得分:4)

跳过$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();
?>

答案 1 :(得分:4)

如果您希望它的工作方式与之前相同,则不应将$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将是字符串&#39; foo&#39;,不是 $ex对象。

根据您在3v4l.org链接中可以看到的不同版本的输出,从7.0.0-7.0.6开始有一段短暂的时间段$this参数显然会被忽略而有利于对象自引用。我假设他们不允许在以后的版本中使用$this作为参数来避免$this在闭包范围中实际引用的含糊不清。

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

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

答案 2 :(得分:-1)

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