Schwerwiegender PHP-Fehler: Verwenden Sie $ this, wenn Sie sich nicht im Objektkontext befinden

137

Ich habe ein Problem:

Ich schreibe eine neue WebApp ohne Framework.

In meiner index.php verwende ich:require_once('load.php');

Und in load.php lade ich require_once('class.php');meine class.php .

In meiner class.php habe ich diesen Fehler:

Schwerwiegender Fehler: Verwenden Sie $ this, wenn Sie sich nicht im Objektkontext in class.php online befinden ... (in diesem Beispiel wäre es 11)

Ein Beispiel, wie meine class.php geschrieben ist:

class foobar {

    public $foo;

    public function __construct() {
        global $foo;

        $this->foo = $foo;
    }

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

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

In meiner index.php lade ich vielleicht foobarfunc()so:

foobar::foobarfunc();

kann aber auch sein

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

Warum kommt der Fehler?

ahmet2106
quelle
2
Zufälligerweise hatte ich gestern ungefähr 3 Stunden mit diesem Fehler zu kämpfen! :)
Jack

Antworten:

184

In meiner index.php lade ich vielleicht foobarfunc () so:

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

kann aber auch sein

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

Sie können die Methode auf diese Weise nicht aufrufen, da es sich nicht um eine statische Methode handelt.

foobar::foobarfunc();

Sie sollten stattdessen verwenden:

foobar->foobarfunc();

Wenn Sie jedoch eine statische Methode erstellt haben, wie zum Beispiel:

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

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

dann können Sie dies verwenden:

foobar::foobarfunc();
Sarfraz
quelle
1
Die gleichnamigen Variablen sind kein Problem. $this->fooist ein Klassenmitglied, während $fooes nur eine Variable im Funktionsbereich ist (aus dem globalen Bereich importiert). Funktionsnamen mit demselben Namen wie ein Mitglied sind ebenfalls kein Problem.
Gordon
157
Sie können nicht $thisin einer statischen Methode verwenden.
Yacoby
5
Es ist lustig, wie eine völlig falsche Antwort trotzdem positive Stimmen erhält. $ Dies ist im Klassenkontext nicht verfügbar. Das OP erhält den gleichen Fehler wie im obigen Beispiel.
Gordon
4
@Sarfraz Nichts für ungut, aber es ist immer noch falsch. Sie können eine Instanzmethode mit aufrufen ::. Es ist dagegen E_STRICT, aber es funktioniert , solange der Methodenkörper nicht auf den Instanzbereich verweist, z $this. B. verwendet . Auch self::foowird nicht darauf hinweisen $this->foo. Es verweist auf eine Klasse konstant . Beides self::foound self::$foowürde einen schwerwiegenden Fehler auslösen.
Gordon
3
@Sarfraz es ist jetzt besser. Es tut mir leid, dass ich Sie belästigt habe, aber als dies die akzeptierte Antwort wurde, hielt ich es für notwendig, auf diese Dinge hinzuweisen :) Vielen Dank für Ihre Geduld.
Gordon
27

Sie rufen eine nicht statische Methode auf:

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

Verwenden eines statischen Aufrufs:

foobar::foobarfunc();

Bei Verwendung eines statischen Aufrufs wird die Funktion aufgerufen (auch wenn sie nicht als deklariert ist static) , aber da es keine Instanz eines Objekts gibt, gibt es keine$this .

So :

  • Sie sollten keine statischen Aufrufe für nicht statische Methoden verwenden
  • Ihre statischen Methoden (oder statisch aufgerufenen Methoden) können $ this nicht verwenden, was normalerweise auf die aktuelle Instanz der Klasse verweist, da bei Verwendung statischer Aufrufe keine Klasseninstanz vorhanden ist.


Hier verwenden die Methoden Ihrer Klasse die aktuelle Instanz der Klasse, da sie auf die zugreifen müssen $foo Eigenschaft der Klasse .

Dies bedeutet, dass Ihre Methoden eine Instanz der Klasse benötigen - was bedeutet, dass sie nicht statisch sein können.

Dies bedeutet, dass Sie keine statischen Aufrufe verwenden sollten: Sie sollten die Klasse instanziieren und das Objekt verwenden, um die Methoden aufzurufen, wie Sie es in Ihrem letzten Teil des Codes getan haben:

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


Für weitere Informationen lesen Sie bitte das PHP-Handbuch:


Beachten Sie auch, dass Sie diese Zeile in Ihrer __constructMethode wahrscheinlich nicht benötigen :

global $foo;

Wenn Sie das globalSchlüsselwort verwenden, wird die $fooaußerhalb aller Funktionen und Klassen deklarierte Variable innerhalb dieser Methode sichtbar ... Und Sie haben wahrscheinlich keine solche $fooVariable.

Um auf die $foo class-Eigenschaft zuzugreifen , müssen Sie nur verwenden $this->foo, wie Sie es getan haben.

Pascal MARTIN
quelle
11

Wenn Sie foobarfuncmit dem Auflösungsbereichsoperator ( ::) aufrufen , rufen Sie ihn statisch auf , z. B. auf Klassenebene anstelle der Instanzebene, und verwenden ihn daher , $thiswenn Sie sich nicht im Objektkontext befinden . $thisexistiert nicht im Klassenkontext.

Wenn Sie aktivieren E_STRICT, wird PHP einen Hinweis dazu auslösen:

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

Tun Sie dies stattdessen

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

Nebenbei schlage ich vor, nicht in globalIhren Klassen zu verwenden. Wenn Sie innerhalb Ihrer Klasse etwas von außerhalb benötigen, übergeben Sie es dem Konstruktor. Dies wird als Abhängigkeitsinjektion bezeichnet und macht Ihren Code viel wartbarer und weniger abhängig von äußeren Dingen.

Gordon
quelle
6

Zuerst verstehen Sie eine Sache: $ this innerhalb einer Klasse bezeichnet das aktuelle Objekt .
Das heißt, Sie werden außerhalb der Klasse erstellt, um die Klassenfunktion oder -variable aufzurufen.

Wenn Sie also Ihre Klassenfunktion wie foobar :: foobarfunc () aufrufen, wird kein Objekt erstellt. Aber innerhalb dieser Funktion, die Sie geschrieben haben, geben Sie $ this-> foo () zurück. Nun hier $ das ist nichts. Deshalb heißt es: Verwenden Sie $ this, wenn Sie sich nicht im Objektkontext in class.php befinden

Lösungen:

  1. Erstellen Sie ein Objekt und rufen Sie foobarfunc () auf.

  2. Rufen Sie foo () mit dem Klassennamen im foobarfunc () auf.

Ramasamy Kasi
quelle
2
oder verwenden Sie einfach self :: anstelle von $ this
Motassem MK
4

Wenn Sie die Funktion in einem statischen Kontext aufrufen, $this einfach nicht.

Sie müssten verwenden this::xyz() stattdessen verwenden.

Um herauszufinden, in welchem ​​Kontext Sie sich befinden, wenn eine Funktion sowohl statisch als auch in einer Objektinstanz aufgerufen werden kann, wird in dieser Frage ein guter Ansatz beschrieben: Wie kann festgestellt werden , ob ich statisch oder ein Objekt bin?

Pekka
quelle
4

Schnelle Methode: (new foobar ()) -> foobarfunc ();

Sie müssen Ihre Klasse ersetzen ersetzen:

foobar::foobarfunc();

durch :

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

oder :

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

Oder machen Sie statische Funktion zu verwenden foobar::.

class foobar {
    //...

    static function foobarfunc() {
        return $this->foo();
    }
}
A-312
quelle
0

$foobar = new foobar;Setzen Sie die Klasse foobar in $ foobar, nicht das Objekt . Um das Objekt zu erhalten, müssen Sie Klammern hinzufügen:$foobar = new foobar();

Ihr Fehler ist einfach, dass Sie eine Methode für eine Klasse aufrufen, sodass es keine gibt, $thisda sie $thisnur in Objekten vorhanden ist.

e-satis
quelle
0

Es scheint mir ein Fehler in PHP zu sein. Der Fehler

'Schwerwiegender Fehler: Nicht erfasster Fehler: Verwenden von $ this, wenn nicht im Objektkontext in'

erscheint in der Funktion using $this, aber der Fehler ist, dass die aufrufende Funktion die nicht statische Funktion als statische Funktion verwendet. Dh:

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

Während der Fehler hier ist:

Class_Name::foo();
Yaakov Aglamaz
quelle
-2

Verwenden Sie dazu einfach die Class-Methode foobar->foobarfunc();

Manobendronath Biswas
quelle
2
Bitte beantworten Sie alte Fragen nur, wenn Sie etwas Neues hinzufügen möchten.
Ajean