Error fatal de PHP: usar $ this cuando no está en el contexto del objeto

137

Tengo un problema:

Estoy escribiendo una nueva aplicación web sin un marco.

En mi index.php estoy usando:require_once('load.php');

Y en load.php estoy usando require_once('class.php');para cargar mi class.php .

En mi class.php tengo este error:

Error fatal: usar $ this cuando no está en el contexto del objeto en class.php en línea ... (en este ejemplo sería 11)

Un ejemplo de cómo se escribe mi 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;
    }
}

En mi index.php estoy cargando tal vez foobarfunc()así:

foobar::foobarfunc();

pero también puede ser

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

¿Por qué viene el error?

ahmet2106
fuente
2
Casualmente, ayer estuve luchando con este error durante aproximadamente 3 horas. :)
Jack

Respuestas:

184

En mi index.php estoy cargando tal vez foobarfunc () así:

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

pero también puede ser

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

No puede invocar el método de esta manera porque no es un método estático.

foobar::foobarfunc();

En su lugar, debe usar:

foobar->foobarfunc();

Sin embargo, si ha creado un método estático similar a:

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

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

entonces puedes usar esto:

foobar::foobarfunc();
Sarfraz
fuente
1
Las variables que tienen el mismo nombre no son un problema. $this->fooes un miembro de la clase, mientras que $fooes solo una variable en el alcance de la función (importado del alcance global). Los nombres de funciones con el mismo nombre que un miembro tampoco son un problema.
Gordon
157
No se puede usar $thisen un método estático.
Yacoby
55
Es curioso cómo una respuesta completamente incorrecta obtiene votos positivos, no obstante. $ esto no está disponible en el contexto de la clase. El OP obtendrá el mismo error del ejemplo anterior.
Gordon
44
@Sarfraz Sin ofender, pero todavía está mal. Usted puede llamar a un método de instancia con ::. Es contra E_STRICT, pero hace el trabajo, siempre y cuando el cuerpo del método no hace referencia al alcance ejemplo, por ejemplo usos $this. Además, self::foono señalará a $this->foo. Hace referencia a una constante de clase . Ambos, self::fooy self::$fooplantearían un error fatal.
Gordon
3
@Sarfraz es mejor ahora. Perdón por molestarlo, pero como se convirtió en la respuesta aceptada, sentí que era necesario señalar estas cosas :) Gracias por su paciencia.
Gordon
27

Está llamando a un método no estático:

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

Usando una llamada estática:

foobar::foobarfunc();

Cuando se utiliza una llamada estática, se llamará a la función (incluso si no se declara como static) , pero, como no hay una instancia de un objeto, no la hay $this.

Entonces :

  • No debe usar llamadas estáticas para métodos no estáticos
  • Sus métodos estáticos (o métodos llamados estáticamente) no pueden usar $ this, que normalmente apunta a la instancia actual de la clase, ya que no hay una instancia de clase cuando usa llamadas estáticas.


Aquí, los métodos de su clase están utilizando la instancia actual de la clase, ya que necesitan acceder a la $foopropiedad de la clase.

Esto significa que sus métodos necesitan una instancia de la clase, lo que significa que no pueden ser estáticos.

Esto significa que no debe usar llamadas estáticas: debe instanciar la clase y usar el objeto para llamar a los métodos, como lo hizo en su última porción de código:

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


Para más información, no dude en leer, en el manual de PHP:


También tenga en cuenta que probablemente no necesite esta línea en su __constructmétodo:

global $foo;

El uso de la globalpalabra clave hará que la $foovariable, declarada fuera de todas las funciones y clases, sea visible desde el interior de ese método ... Y probablemente no tenga esa $foovariable.

Para acceder a la $foo propiedad de clase , solo necesita usar $this->foo, como lo hizo.

Pascal MARTIN
fuente
11

Si está invocando foobarfunccon el operador de alcance de resolución ( ::), lo está llamando estáticamente , por ejemplo, en el nivel de clase en lugar del nivel de instancia, por lo que está utilizando $thiscuando no está en el contexto del objeto . $thisno existe en el contexto de clase.

Si habilita E_STRICT, PHP generará un Aviso sobre esto:

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

Haz esto en su lugar

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

En una nota al margen, sugiero no usar globaldentro de sus clases. Si necesita algo externo a su clase, páselo por el constructor. Esto se llama inyección de dependencia y hará que su código sea mucho más fácil de mantener y menos dependiente de cosas externas.

Gordon
fuente
6

Primero entiendes una cosa, $ this dentro de una clase denota el objeto actual .
Eso es lo que se crea fuera de la clase para llamar a la función o variable de clase.

Entonces, cuando está llamando a su función de clase como foobar :: foobarfunc (), el objeto no se crea. Pero dentro de esa función que escribiste, devuelve $ this-> foo (). Ahora aquí $ esto no es nada. Es por eso que dice Usar $ this cuando no está en el contexto del objeto en class.php

Soluciones:

  1. Cree un objeto y llame a foobarfunc ().

  2. Llame a foo () usando el nombre de la clase dentro de foobarfunc ().

Ramasamy Kasi
fuente
2
o simplemente use self :: en lugar de $ this
Motassem MK
4

Cuando llama a la función en un contexto estático, $thissimplemente no existe.

Tendría que usar this::xyz()en su lugar.

Para saber en qué contexto se encuentra cuando una función se puede llamar estáticamente y en una instancia de objeto, se describe un buen enfoque en esta pregunta: ¿Cómo saber si soy estático o un objeto?

Pekka
fuente
4

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

Necesita cargar su clase reemplazar:

foobar::foobarfunc();

por:

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

o:

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

O hacer una función estática para usar foobar::.

class foobar {
    //...

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

$foobar = new foobar;pon la clase foobar en $ foobar, no el objeto . Para obtener el objeto, debe agregar paréntesis:$foobar = new foobar();

Su error es simplemente que llama a un método en una clase, por lo que no existe $thisya que $thissolo existe en los objetos.

e-satis
fuente
0

Me parece ser un error en PHP. El error

'Error fatal: Error no detectado: Uso de $ this cuando no está en el contexto del objeto en'

aparece en la función usando $this, pero el error es que la función de llamada está usando una función no estática como estática. Es decir:

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

Mientras el error está aquí:

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

Simplemente use el método Class usando esto foobar->foobarfunc();

Manobendronath Biswas
fuente
2
Solo responda preguntas anteriores si tiene algo nuevo que agregar.
Ajean