【问题标题】:PHP Fatal error: Using $this when not in object contextPHP 致命错误:不在对象上下文中使用 $this
【发布时间】:2011-01-21 23:56:27
【问题描述】:

我有一个问题:

我正在编写一个没有框架的新 WebApp。

在我的 index.php 我正在使用:require_once('load.php');

load.php 中,我使用 require_once('class.php'); 来加载我的 class.php

在我的 class.php 中出现此错误:

致命错误:当不在 class.php 的对象上下文中时使用 $this ...(在本例中为 11)

我的 class.php 是如何编写的示例:

class foobar {

    public $foo;

    public function __construct() {
        global $foo;

        $this->foo = $foo;
    }

    public function foobarfunc() {
        return $this->foo();
    }

    public function foo() {
        return $this->foo;
    }
}

在我的 index.php 中,我可能正在加载 foobarfunc(),如下所示:

foobar::foobarfunc();

但也可以

$foobar = new foobar;
$foobar->foobarfunc();

为什么会出现错误?

【问题讨论】:

  • 巧合的是,我昨天在这个错误中挣扎了大约 3 个小时! :)
  • @jack 在我的情况下,我在静态函数上使用 this

标签: php function class object fatal-error


【解决方案1】:

在我的 index.php 中,我可能正在加载 foob​​arfunc() 像这样:

 foobar::foobarfunc();  // Wrong, it is not static method

但也可以

$foobar = new foobar;  // correct
$foobar->foobarfunc();

你不能这样调用方法,因为它不是静态方法。

foobar::foobarfunc();

你应该改用:

foobar->foobarfunc();

但是,如果您创建了类似的静态方法:

static $foo; // your top variable set as static

public static function foo() {
    return self::$foo;
}

那么你可以使用这个:

foobar::foobarfunc();

【讨论】:

  • 同名的变量不是问题。 $this->foo 是一个类成员,而 $foo 只是函数范围内的一个变量(从全局范围导入)。与成员同名的函数名也不是问题。
  • 您不能在静态方法中使用$this
  • 有趣的是,一个完全错误的答案如何得到支持。 $this 在类上下文中不可用。 OP 会从上面的例子中得到同样的错误。
  • @Sarfraz 没有冒犯,但它仍然是错误的。您可以使用:: 调用实例方法。它反对E_STRICT,但只要方法体不引用实例范围,它确实工作,例如使用$this。此外,self::foo 不会指向$this->foo。它引用了一个类constantself::fooself::$foo 都会引发致命错误。
  • @Sarfraz 现在好多了。很抱歉打扰您,但由于这已成为公认的答案,我觉得有必要指出这些事情:) 感谢您的耐心等待。
【解决方案2】:

你正在调用一个非静态方法:

public function foobarfunc() {
    return $this->foo();
}

使用静态调用:

foobar::foobarfunc();

当使用静态调用时,函数将被调用(即使没有声明为static,但是,因为没有对象的实例,所以没有$this .

所以:

  • 您不应该对非静态方法使用静态调用
  • 您的静态方法(或静态调用的方法)不能使用 $this,它通常指向类的当前实例,因为在使用静态调用时没有类实例。


在这里,您的类的方法正在使用该类的当前实例,因为它们需要访问该类的$foo 属性。

这意味着你的方法需要一个类的实例——这意味着它们不能是静态的。

这意味着你不应该使用静态调用:你应该实例化类,并使用对象来调用方法,就像你在最后一部分代码中所做的那样:

$foobar = new foobar();
$foobar->foobarfunc();


欲了解更多信息,请不要犹豫,阅读 PHP 手册:


另请注意,您的 __construct 方法中可能不需要此行:

global $foo;

使用global keyword 将使$foo 变量在所有函数和类之外声明,从该方法内部可见...而且您可能没有这样的$foo 变量。

要访问$fooclass-property,您只需要像您一样使用$this->foo

【讨论】:

    【解决方案3】:

    如果您使用resolution scope operator (::) 调用foobarfunc,那么您将调用它statically,例如在类级别而不是实例级别,因此您在不在对象上下文中时使用$this$this 在类上下文中不存在。

    如果你启用E_STRICT,PHP 会发出一个通知:

    Strict Standards: 
    Non-static method foobar::foobarfunc() should not be called statically
    

    改为这样做

    $fb = new foobar;
    echo $fb->foobarfunc();
    

    顺便说一句,我建议不要在你的课程中使用global。如果您在类内部需要某些东西,请将其传递给构造函数。这称为Dependency Injection,它将使您的代码更易于维护,并且更少依赖外部事物。

    【讨论】:

      【解决方案4】:

      首先你要明白一件事,类中的$this表示当前对象
      那就是你在类之外创建来调用类函数或变量。

      因此,当您调用 foobar::foobarfunc() 之类的类函数时,不会创建对象。 但是在你编写的那个函数里面返回 $this->foo()。现在这里 $this 什么都不是。这就是为什么它说 在 class.php 中不在对象上下文中时使用 $this

      解决方案:

      1. 创建一个对象并调用 foobarfunc()。

      2. 使用 foobarfunc() 中的类名调用 foo()。

      【讨论】:

      • 或者只使用 self:: 而不是 $this
      【解决方案5】:

      当您在静态上下文中调用函数时,$this 根本不存在。

      您必须改用this::xyz()

      要找出可以在静态和对象实例中调用函数时所处的上下文,这个问题概述了一个好方法:How to tell whether I’m static or an object?

      【讨论】:

        【解决方案6】:

        快速方法:(new foobar())->foobarfunc();

        你需要加载你的类替换:

        foobar::foobarfunc();
        

        作者:

        (new foobar())->foobarfunc();
        

        或:

        $Foobar = new foobar();
        $Foobar->foobarfunc();
        

        或者使static函数使用foobar::

        class foobar {
            //...
        
            static function foobarfunc() {
                return $this->foo();
            }
        }
        

        【讨论】:

          【解决方案7】:

          在我看来这是 PHP 中的一个错误。 错误

          '致命错误:未捕获错误:不在对象上下文中使用 $this 在'

          出现在使用$this的函数中,但错误是调用函数是使用非静态函数作为静态的。即:

          Class_Name
          {
              function foo()
              {
                  $this->do_something(); // The error appears there.
              }
              function do_something()
              {
                  ///
              }
          }
          

          虽然错误在这里:

          Class_Name::foo();
          

          【讨论】:

            【解决方案8】:

            $foobar = new foobar; foobar 放入 $foobar,不是对象。获取对象需要加括号:$foobar = new foobar();

            你的错误只是你在一个类上调用了一个方法,所以没有$this,因为$this只存在于对象中。

            【讨论】:

              【解决方案9】:

              只需使用 foobar->foobarfunc(); 的 Class 方法

              【讨论】:

              • 如果您有要添加的内容,请仅回答旧问题。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-12-11
              • 1970-01-01
              相关资源
              最近更新 更多