Errore irreversibile PHP: utilizzo di $ this quando non si trova nel contesto dell'oggetto


137

Ho un problema:

Sto scrivendo una nuova WebApp senza un framework.

Nel mio index.php sto usando:require_once('load.php');

E in load.php sto usando require_once('class.php');per caricare il mio class.php .

Nel mio class.php ho questo errore:

Errore irreversibile: usare $ this quando non è nel contesto dell'oggetto in class.php on line ... (in questo esempio sarebbe 11)

Un esempio di come è scritto il mio 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;
    }
}

Nel mio index.php sto caricando forse in foobarfunc()questo modo:

foobar::foobarfunc();

ma può anche essere

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

Perché sta arrivando l'errore?


2
Per coincidenza stavo lottando con questo errore per circa 3 ore ieri! :)
Jack,

Risposte:


184

Nel mio index.php sto caricando forse foobarfunc () in questo modo:

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

ma può anche essere

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

Non è possibile richiamare il metodo in questo modo perché non è un metodo statico.

foobar::foobarfunc();

Dovresti invece usare:

foobar->foobarfunc();

Se tuttavia hai creato un metodo statico simile al seguente:

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

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

allora puoi usare questo:

foobar::foobarfunc();

1
Le variabili con lo stesso nome non sono un problema. $this->fooè un membro della classe, mentre $fooè solo una variabile nell'ambito della funzione (importata dall'ambito globale). Anche i nomi delle funzioni con lo stesso nome di un membro non sono un problema.
Gordon,

157
Non è possibile utilizzare $thisin un metodo statico.
Yacoby,

5
È divertente come una risposta completamente sbagliata riceva comunque voti. $ questo non è disponibile nel contesto di classe. L'OP otterrà lo stesso errore dall'esempio sopra.
Gordon,

4
@Sarfraz Senza offesa, ma è ancora sbagliato. È possibile chiamare un metodo di istanza con ::. È contro E_STRICT, ma fa lavoro fintanto che il corpo del metodo non fa riferimento la portata esempio, utilizza es $this. Inoltre, self::foonon indicherà $this->foo. Fa riferimento a una costante di classe . Entrambi self::fooe self::$foogenererebbero un errore fatale.
Gordon,

3
@Sarfraz ora è meglio. Ci scusiamo per averti infastidito, ma poiché questa è diventata la risposta accettata, ho ritenuto necessario sottolineare queste cose :) Grazie per la tua pazienza.
Gordon,

27

Stai chiamando un metodo non statico:

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

Utilizzando una chiamata statica:

foobar::foobarfunc();

Quando si utilizza una chiamata statica, la funzione verrà chiamata (anche se non dichiarata come static) , ma, poiché non esiste un'istanza di un oggetto, non esiste $this.

Così :

  • Non utilizzare le chiamate statiche per metodi non statici
  • I tuoi metodi statici (o metodi chiamati staticamente) non possono usare $ this, che normalmente punta all'istanza corrente della classe, poiché non esiste un'istanza di classe quando usi le chiamate statiche.


Qui, i metodi della tua classe utilizzano l'istanza corrente della classe, poiché devono accedere alla $fooproprietà della classe.

Ciò significa che i tuoi metodi richiedono un'istanza della classe, il che significa che non possono essere statici.

Questo significa che non dovresti usare chiamate statiche: dovresti istanziare la classe e usare l'oggetto per chiamare i metodi, come hai fatto nell'ultima parte di codice:

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


Per maggiori informazioni, non esitate a leggere, nel manuale di PHP:


Si noti inoltre che probabilmente non è necessaria questa riga nel __constructmetodo:

global $foo;

L'uso della globalparola chiave renderà la $foovariabile, dichiarata al di fuori di tutte le funzioni e classi, visibile dall'interno di quel metodo ... E probabilmente non hai una tale $foovariabile.

Per accedere alla $foo proprietà class , devi solo usare $this->foo, come hai fatto tu.


11

Se si sta invocando foobarfunccon l' operatore scope scope ( ::), lo si chiama in modo statico , ad es. A livello di classe anziché a livello di istanza, quindi si utilizza $thisquando non si è nel contesto dell'oggetto . $thisnon esiste nel contesto di classe.

Se abiliti E_STRICT, PHP solleverà un avviso a riguardo:

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

Fallo invece

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

Su un sidenote, suggerisco di non usare globalall'interno delle tue lezioni. Se hai bisogno di qualcosa dall'esterno all'interno della tua classe, passalo attraverso il costruttore. Questo si chiama Dependency Injection e renderà il tuo codice molto più gestibile e meno dipendente da cose esterne.


6

Per prima cosa capisci una cosa, $ this all'interno di una classe indica l' oggetto corrente .
È per questo che sei creato fuori dalla classe per chiamare la funzione o la variabile di classe.

Quindi quando chiami la tua funzione di classe come foobar :: foobarfunc (), l'oggetto non viene creato. Ma all'interno di quella funzione hai scritto return $ this-> foo (). Ora qui $ questo non è niente. Ecco perché sta dicendo Usando $ this quando non nel contesto dell'oggetto in class.php

soluzioni:

  1. Crea un oggetto e chiama foobarfunc ().

  2. Chiama foo () usando il nome della classe all'interno di foobarfunc ().


2
o semplicemente usa self :: invece di $ this
Motassem MK

4

Quando si chiama la funzione in un contesto statico, $this semplicemente non esiste.

Dovresti usare this::xyz() invece.

Per scoprire in quale contesto ti trovi quando una funzione può essere chiamata sia staticamente sia in un'istanza di oggetto, in questa domanda è delineato un buon approccio: come capire se sono statico o un oggetto?


4

Metodo rapido: (new foobar ()) -> foobarfunc ();

È necessario caricare la sostituzione della classe:

foobar::foobarfunc();

di:

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

o :

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

Oppure crea una funzione statica da usare foobar::.

class foobar {
    //...

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

0

$foobar = new foobar;metti il foobar di classe in $ foobar, non l'oggetto . Per ottenere l'oggetto, è necessario aggiungere una parentesi:$foobar = new foobar();

Il tuo errore è semplicemente che si chiama un metodo su una classe, quindi non esiste $thispoiché $thisesiste solo negli oggetti.


0

Mi sembra un bug in PHP. L'errore

"Errore irreversibile: errore non rilevato: utilizzo di $ this quando non nel contesto dell'oggetto in"

appare nella funzione utilizzando $this, ma l'errore è che la funzione chiamante utilizza una funzione non statica come statica. Vale a dire:

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

Mentre l'errore è qui:

Class_Name::foo();

-2

Usa semplicemente il metodo Class usando questo foobar->foobarfunc();


2
Rispondi alle vecchie domande solo se hai qualcosa di nuovo da aggiungere.
Ajean,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.