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

Posted

技术标签:

【中文标题】PHP 致命错误:不在对象上下文中使用 $this【英文标题】:PHP Fatal error: Using $this when not in object context 【发布时间】: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 【参考方案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 手册:

Classes and Objects 部分 还有Static Keyword 页面。

另请注意,您的 __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

解决方案:

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

    使用 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 方法

【讨论】:

如果您有要添加的内容,请仅回答旧问题。

以上是关于PHP 致命错误:不在对象上下文中使用 $this的主要内容,如果未能解决你的问题,请参考以下文章

在静态函数中使用 $this 失败

致命错误:“break”不在“loop”或“switch”上下文中

PHP - 致命错误:无法在写入上下文中使用方法返回值

PHP 致命错误:未捕获的错误:无法使用 mysqli 类型的对象作为数组

尝试使用 Mysqli 插入时,我得到“不在对象上下文中使用 $this”

了解致命错误:无法在写入上下文中使用临时表达式