161

我有一个问题:

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

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

load.phprequire_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();

为什么会出现错误?

4

9 回答 9

227

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

 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();
于 2010-02-28T11:56:45.030 回答
32

您正在调用非静态方法:

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

使用静态调用:

foobar::foobarfunc();

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

所以 :

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


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

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

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

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


有关更多信息,请随时阅读 PHP 手册:


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

global $foo;

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

要访问$foo class-property,您只需要使用$this->foo,就像您所做的那样。

于 2010-02-28T11:58:41.627 回答
13

如果您foobarfunc使用解析范围运算符( ::) 进行调用,那么您是在静态调用它,例如在类级别而不是实例级别,因此您在不在对象上下文中时使用$this$this在类上下文中不存在。

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

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

改为这样做

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

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

于 2010-02-28T11:56:46.733 回答
7

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

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

解决方案:

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

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

于 2014-07-11T06:42:10.133 回答
5

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

您将不得不this::xyz()改用。

要找出可以在静态和对象实例中调用函数时所处的上下文,在这个问题中概述了一个好方法:如何判断我是静态的还是对象?

于 2010-02-28T11:58:28.537 回答
5

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

你需要加载你的类替换:

foobar::foobarfunc();

经过 :

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

或者 :

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

或者制作静态函数来使用foobar::

class foobar {
    //...

    static function foobarfunc() {
        return $this->foo();
    }
}
于 2015-12-30T19:52:07.097 回答
2

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

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

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

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

虽然错误在这里:

Class_Name::foo();
于 2020-07-01T07:45:28.467 回答
1

$foobar = new foobar;foobar 放在 $foobar 中,而不是 object。要获取对象,您需要添加括号:$foobar = new foobar();

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

于 2010-02-28T12:21:00.380 回答
0

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

于 2015-11-30T17:01:41.710 回答