PHP致命错误:在不在对象上下文中时使用$ this

ahm*_*106 123 php class function object fatal-error

我有一个问题:

我正在编写一个没有框架的新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;
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的index.php中我加载可能foobarfunc()是这样的:

foobar::foobarfunc();
Run Code Online (Sandbox Code Playgroud)

但也可以

$foobar = new foobar;
$foobar->foobarfunc();
Run Code Online (Sandbox Code Playgroud)

为什么会出现错误?

Sar*_*raz 165

在我的index.php中我可能像这样加载foobarfunc():

 foobar::foobarfunc();  // Wrong, it is not static method
Run Code Online (Sandbox Code Playgroud)

但也可以

$foobar = new foobar;  // correct
$foobar->foobarfunc();
Run Code Online (Sandbox Code Playgroud)

您无法以这种方式调用方法,因为它不是静态方法.

foobar::foobarfunc();
Run Code Online (Sandbox Code Playgroud)

您应该使用:

foobar->foobarfunc();
Run Code Online (Sandbox Code Playgroud)

但是,如果您创建了一个静态方法,例如:

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

public static function foo() {
    return self::$foo;
}
Run Code Online (Sandbox Code Playgroud)

然后你可以用这个:

foobar::foobarfunc();
Run Code Online (Sandbox Code Playgroud)

  • 你不能在静态方法中使用`$ this`. (143认同)
  • 尽管如此,一个完全错误的答案如何获得回报也很有趣.$ this在类上下文中不可用.OP将从上面的示例中获得相同的错误. (4认同)
  • @Sarfraz没有冒犯,但它仍然是错误的.你*可以用`::`调用一个实例方法.它反对`E_STRICT`,但只要方法体不引用实例范围,它就*工作*,例如使用`$ this`.另外,`self :: foo`不会指向`$ this-> foo`.它引用了一个类**常量**.两者,`self :: foo`和`self :: $ foo`都会引发致命错误. (4认同)
  • @Sarfraz现在好多了.很抱歉缠着你,但是因为这成了公认的答案,我觉得有必要指出这些事情:)谢谢你的耐心等待. (2认同)

Pas*_*TIN 26

您正在调用非静态方法:

public function foobarfunc() {
    return $this->foo();
}
Run Code Online (Sandbox Code Playgroud)

使用静态调用:

foobar::foobarfunc();
Run Code Online (Sandbox Code Playgroud)

当使用静态调用时,将调用该函数(即使未声明为static),但由于没有对象的实例,因此没有$this.

所以:

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


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

这意味着您的方法需要类的实例 - 这意味着它们不能是静态的.

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

$foobar = new foobar();
$foobar->foobarfunc();
Run Code Online (Sandbox Code Playgroud)


有关更多信息,请在PHP手册中不要犹豫:


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

global $foo;
Run Code Online (Sandbox Code Playgroud)

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

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


Gor*_*don 11

如果您正在调用foobarfunc分辨率范围操作符(::),那么你就调用它静态地,例如在类级别而不是实例级,因此你$this不用时对象上下文.$this在类上下文中不存在.

如果启用E_STRICT,PHP将发出关于此的通知:

Strict Standards: 
Non-static method foobar::foobarfunc() should not be called statically
Run Code Online (Sandbox Code Playgroud)

这样做

$fb = new foobar;
echo $fb->foobarfunc();
Run Code Online (Sandbox Code Playgroud)

在旁注中,我建议不要global在课堂内使用.如果您需要在课堂外部进行某些操作,请将其传递给构造函数.这称为依赖注入,它将使您的代码更易于维护,并减少对外部事物的依赖.


小智 6

首先你理解一件事,一个类中的$ this表示当前对象.
那就是你在类的一侧创建调用类函数或变量.

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

解决方案:

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

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

  • 或者只是使用 self:: 而不是 $this (3认同)

Pek*_*ica 5

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

\n\n

你将不得不使用this::xyz()

\n\n

为了找出当一个函数可以静态调用和在对象实例中调用时您所处的上下文,这个问题概述了一个很好的方法:如何判断 I\xe2\x80\x99m static 还是 object?

\n


A-3*_*312 5

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

你需要加载你的类替换:

foobar::foobarfunc();
Run Code Online (Sandbox Code Playgroud)

经过 :

(new foobar())->foobarfunc();
Run Code Online (Sandbox Code Playgroud)

或者 :

$Foobar = new foobar();
$Foobar->foobarfunc();
Run Code Online (Sandbox Code Playgroud)

或者使静态函数使用foobar::.

class foobar {
    //...

    static function foobarfunc() {
        return $this->foo();
    }
}
Run Code Online (Sandbox Code Playgroud)