Erro fatal do PHP: usar $ this quando não estiver no contexto do objeto

137

Eu tenho um problema:

Estou escrevendo um novo WebApp sem um Framework.

No meu index.php eu estou usando:require_once('load.php');

E no load.php eu estou usando require_once('class.php');para carregar meu class.php .

No meu class.php eu tenho este erro:

Erro fatal: usar $ this quando não estiver no contexto do objeto em class.php on line ... (neste exemplo, seria 11)

Um exemplo de como meu class.php está escrito:

class foobar {

    public $foo;

    public function __construct() {
        global $foo;

        $this->foo = $foo;
    }

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

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

No meu index.php eu estou carregando talvez foobarfunc()assim:

foobar::foobarfunc();

mas também pode ser

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

Por que o erro está chegando?

ahmet2106
fonte
2
Coincidentemente, eu estava lutando com esse erro por cerca de 3 horas ontem! :)
Jack

Respostas:

184

No meu index.php eu estou carregando talvez foobarfunc () assim:

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

mas também pode ser

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

Você não pode invocar o método dessa maneira porque não é um método estático.

foobar::foobarfunc();

Você deve usar:

foobar->foobarfunc();

Se, no entanto, você criou um método estático, algo como:

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

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

então você pode usar isso:

foobar::foobarfunc();
Sarfraz
fonte
1
As variáveis ​​com o mesmo nome não são um problema. $this->fooé um membro da classe, enquanto $fooé apenas uma variável no escopo da função (importada do escopo global). Nomes de funções com o mesmo nome que um membro também não são um problema.
28710 Gordon
157
Você não pode usar $thisem um método estático.
Yacoby
5
É engraçado como uma resposta completamente errada é positiva mesmo assim. $ this não está disponível no contexto de classe. O OP receberá o mesmo erro do exemplo acima.
28710 Gordon
4
@ Sarfraz Sem ofensas, mas ainda está errado. Você pode chamar um método de instância com ::. É contra E_STRICT, mas faz o trabalho, enquanto o corpo do método não faz referência ao âmbito exemplo, por exemplo, usos $this. Além disso, self::foonão apontará para $this->foo. Referencia uma constante de classe . Ambos, self::fooe self::$foogeraria um erro fatal.
28710 Gordon
3
@ Sarfraz é melhor agora. Desculpe por incomodá-lo, mas, como essa se tornou a resposta aceita, achei necessário salientar essas coisas :) Obrigado pela paciência.
Gordon
27

Você está chamando um método não estático:

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

Usando uma chamada estática:

foobar::foobarfunc();

Ao usar uma chamada estática, a função será chamada (mesmo que não seja declarada como static) , mas, como não há instância de um objeto, não há$this .

Assim :

  • Você não deve usar chamadas estáticas para métodos não estáticos
  • Seus métodos estáticos (ou métodos chamados estaticamente) não podem usar $ this, que normalmente aponta para a instância atual da classe, pois não há instância de classe quando você está usando chamadas estáticas.


Aqui, os métodos da sua classe estão usando a instância atual da classe, pois eles precisam acessar a $foopropriedade da classe.

Isso significa que seus métodos precisam de uma instância da classe - o que significa que eles não podem ser estáticos.

Isso significa que você não deve usar chamadas estáticas: você deve instanciar a classe e usar o objeto para chamar os métodos, como você fez na última parte do código:

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


Para mais informações, não hesite em ler, no manual do PHP:


Observe também que você provavelmente não precisa desta linha no seu __constructmétodo:

global $foo;

Usar a globalpalavra - chave fará com que a $foovariável declarada fora de todas as funções e classes fique visível de dentro desse método ... E você provavelmente não tem essa$foo variável.

Para acessar a $foo propriedade de classe , você só precisa usar $this->foo, como fez.

Pascal MARTIN
fonte
11

Se você está chamando foobarfunccom o operador de escopo de resolução ( ::), está chamando-o estaticamente , por exemplo, no nível da classe em vez do nível da instância, assim você está usando $thisquando não está no contexto do objeto . $thisnão existe no contexto de classe.

Se você ativar E_STRICT, o PHP emitirá um aviso sobre isso:

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

Faça isso

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

Em uma nota de rodapé, sugiro não usar globalnas suas aulas. Se você precisar de algo externo à sua classe, passe-o pelo construtor. Isso se chama Injeção de Dependência e tornará seu código muito mais sustentável e menos dependente de coisas externas.

Gordon
fonte
6

Primeiro, você entende uma coisa: $ this dentro de uma classe indica o objeto atual .
Ou seja, você é criado fora da classe para chamar a função ou variável da classe.

Portanto, quando você está chamando sua função de classe como foobar :: foobarfunc (), o objeto não é criado. Mas dentro dessa função que você escreveu, retorne $ this-> foo (). Agora aqui $ isso não é nada. É por isso que está dizendo Usar $ this quando não está no contexto do objeto em class.php

Soluções:

  1. Crie um objeto e chame foobarfunc ().

  2. Chame foo () usando o nome da classe dentro do foobarfunc ().

Ramasamy Kasi
fonte
2
ou apenas use self :: em vez de $ this #
Motassem MK
4

Quando você chama a função em um contexto estático, $thissimplesmente não existe.

Você teria que usar em seu this::xyz()lugar.

Para descobrir em que contexto você está quando uma função pode ser chamada estaticamente e em uma instância de objeto, uma boa abordagem é descrita nesta pergunta: Como saber se eu sou estático ou um objeto?

Pekka
fonte
4

Método rápido: (new foobar ()) -> foobarfunc ();

Você precisa carregar sua classe substituir:

foobar::foobarfunc();

de :

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

ou:

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

Ou crie uma função estática para usar foobar::.

class foobar {
    //...

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

$foobar = new foobar;coloque a classe foobar em $ foobar, não o objeto . Para obter o objeto, você precisa adicionar parênteses:$foobar = new foobar();

Seu erro é simplesmente que você chama um método em uma classe, então não existe, $thispois $thisexiste apenas em objetos.

e-satis
fonte
0

Parece-me um erro no PHP. O erro

'Erro fatal: Erro não capturado: usar $ this quando não estiver no contexto do objeto em'

aparece na função usando $this, mas o erro é que a função de chamada está usando a função não estática como estática. Ou seja:

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

Enquanto o erro está aqui:

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

Basta usar o método Class usando este foobar->foobarfunc();

Manobendronath Biswas
fonte
2
Responda apenas a perguntas antigas se você tiver algo novo a adicionar.
Ajean