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 中,我可能正在加载 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();
【讨论】:
同名的变量不是问题。$this->foo
是一个类成员,而 $foo
只是函数范围内的一个变量(从全局范围导入)。与成员同名的函数名也不是问题。
您不能在静态方法中使用$this
。
有趣的是,一个完全错误的答案如何得到支持。 $this 在类上下文中不可用。 OP 会从上面的例子中得到同样的错误。
@Sarfraz 没有冒犯,但它仍然是错误的。您可以使用::
调用实例方法。它反对E_STRICT
,但只要方法体不引用实例范围,它确实工作,例如使用$this
。此外,self::foo
不会指向$this->foo
。它引用了一个类constant。 self::foo
和 self::$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
变量。
要访问$foo
class-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的主要内容,如果未能解决你的问题,请参考以下文章
致命错误:“break”不在“loop”或“switch”上下文中
PHP 致命错误:未捕获的错误:无法使用 mysqli 类型的对象作为数组