Erreur fatale PHP: utilisation de $ this lorsqu'il n'est pas dans le contexte de l'objet


138

J'ai un problème:

J'écris une nouvelle WebApp sans Framework.

Dans mon index.php, j'utilise:require_once('load.php');

Et dans load.php, j'utilise require_once('class.php');pour charger mon class.php .

Dans mon class.php, j'ai cette erreur:

Erreur fatale: utiliser $ this lorsqu'il n'est pas dans le contexte de l'objet dans class.php en ligne ... (dans cet exemple, ce serait 11)

Un exemple comment mon class.php est écrit:

class foobar {

    public $foo;

    public function __construct() {
        global $foo;

        $this->foo = $foo;
    }

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

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

Dans mon index.php, je charge peut-être foobarfunc()comme ceci:

foobar::foobarfunc();

mais peut aussi être

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

Pourquoi l'erreur vient-elle?


2
Par coïncidence, je luttais avec cette erreur pendant environ 3 heures hier! :)
Jack

Réponses:


184

Dans mon index.php, je charge peut-être foobarfunc () comme ceci:

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

mais peut aussi être

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

Vous ne pouvez pas appeler la méthode de cette façon car ce n'est pas une méthode statique.

foobar::foobarfunc();

Vous devriez plutôt utiliser:

foobar->foobarfunc();

Si toutefois vous avez créé une méthode statique quelque chose comme:

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

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

alors vous pouvez utiliser ceci:

foobar::foobarfunc();

1
Les variables portant le même nom ne sont pas un problème. $this->fooest un membre de la classe, tandis que $foon'est qu'une variable dans la portée de la fonction (importée de la portée globale). Les noms de fonction portant le même nom qu'un membre ne sont pas non plus un problème.
Gordon

157
Vous ne pouvez pas utiliser $thisdans une méthode statique.
Yacoby

5
C'est drôle comme une réponse complètement erronée suscite néanmoins des votes. $ ceci n'est pas disponible dans le contexte de la classe. L'OP obtiendra la même erreur de l'exemple ci-dessus.
Gordon

4
@Sarfraz Aucune offense, mais c'est toujours faux. Vous pouvez appeler une méthode d'instance avec ::. Il est contre E_STRICT, mais il fait le travail aussi longtemps que le corps de la méthode ne fait pas référence à la portée de l' instance, par exemple des utilisations $this. Aussi, self::foone pointera pas vers $this->foo. Il fait référence à une constante de classe . Les deux, self::fooet self::$foosoulèveraient une erreur fatale.
Gordon

3
@Sarfraz c'est mieux maintenant. Désolé de vous avoir harcelé, mais comme c'est devenu la réponse acceptée, j'ai jugé nécessaire de souligner ces choses :) Merci pour votre patience.
Gordon

27

Vous appelez une méthode non statique:

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

Utilisation d'un appel statique:

foobar::foobarfunc();

Lors de l'utilisation d'un appel statique, la fonction sera appelée (même si elle n'est pas déclarée comme static) , mais comme il n'y a pas d'instance d'objet, il n'y en a pas $this.

Alors :

  • Vous ne devez pas utiliser d'appels statiques pour les méthodes non statiques
  • Vos méthodes statiques (ou méthodes appelées statiquement) ne peuvent pas utiliser $ this, qui pointe normalement vers l'instance actuelle de la classe, car il n'y a pas d'instance de classe lorsque vous utilisez des appels statiques.


Ici, les méthodes de votre classe utilisent l'instance actuelle de la classe, car elles doivent accéder à la $foopropriété de la classe.

Cela signifie que vos méthodes ont besoin d'une instance de la classe - ce qui signifie qu'elles ne peuvent pas être statiques.

Cela signifie que vous ne devez pas utiliser d'appels statiques: vous devez instancier la classe et utiliser l'objet pour appeler les méthodes, comme vous l'avez fait dans votre dernière partie de code:

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


Pour plus d'informations, n'hésitez pas à lire, dans le manuel PHP:


Notez également que vous n'avez probablement pas besoin de cette ligne dans votre __constructméthode:

global $foo;

L'utilisation du globalmot - clé rendra la $foovariable, déclarée en dehors de toutes les fonctions et classes, visible de l'intérieur de cette méthode ... Et vous n'avez probablement pas une telle $foovariable.

Pour accéder à la $foo propriété de classe , il vous suffit d'utiliser $this->foo, comme vous l'avez fait.


11

Si vous invoquez foobarfuncavec l' opérateur de portée de résolution ( ::), alors vous l'appelez de manière statique , par exemple au niveau de la classe au lieu du niveau de l'instance, donc vous l' utilisez $thislorsque vous n'êtes pas dans le contexte de l'objet .$thisn'existe pas dans le contexte de la classe.

Si vous activez E_STRICT, PHP lèvera un avis à ce sujet:

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

Faites ceci à la place

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

En passant, je suggère de ne pas utiliser globaldans vos classes. Si vous avez besoin de quelque chose de l'extérieur à l'intérieur de votre classe, passez-le via le constructeur. Cela s'appelle l' injection de dépendances et cela rendra votre code beaucoup plus maintenable et moins dépendant des choses extérieures.


6

D'abord, vous comprenez une chose, $ this à l' intérieur d'une classe désigne l' objet courant .
C'est ce que vous êtes créé en dehors de la classe pour appeler une fonction ou une variable de classe.

Ainsi, lorsque vous appelez votre fonction de classe comme foobar :: foobarfunc (), l'objet n'est pas créé. Mais à l'intérieur de cette fonction, vous avez écrit return $ this-> foo (). Maintenant, ici, ce n'est rien. C'est pourquoi il dit Utiliser $ this lorsqu'il n'est pas dans le contexte de l'objet dans class.php

Solutions:

  1. Créez un objet et appelez foobarfunc ().

  2. Appelez foo () en utilisant le nom de classe dans foobarfunc ().


2
ou utilisez simplement self :: au lieu de $ this
Motassem MK

4

Lorsque vous appelez la fonction dans un contexte statique, $this n'existe tout simplement pas.

Vous auriez à utiliser this::xyz() place.

Pour savoir dans quel contexte vous vous trouvez lorsqu'une fonction peut être appelée à la fois de manière statique et dans une instance d'objet, une bonne approche est décrite dans cette question: Comment savoir si je suis statique ou un objet?


4

Méthode rapide: (new foobar ()) -> foobarfunc ();

Vous devez charger votre classe remplacer:

foobar::foobarfunc();

par :

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

ou :

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

Ou créez une fonction statique à utiliser foobar::.

class foobar {
    //...

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

0

$foobar = new foobar;mettez la classe foobar dans $ foobar, pas l'objet . Pour obtenir l'objet, vous devez ajouter des parenthèses:$foobar = new foobar();

Votre erreur est simplement que vous appelez une méthode sur une classe, il n'y en a donc pas $thiscar $thisil n'existe que dans les objets.


0

Cela me semble être un bug en PHP. L'erreur

'Erreur fatale: erreur non interceptée: utilisation de $ this lorsqu'il n'est pas dans le contexte de l'objet dans'

apparaît dans la fonction using $this, mais l'erreur est que la fonction appelante utilise une fonction non statique en tant que statique. C'est à dire:

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

Tant que l'erreur est là:

Class_Name::foo();

-2

Utilisez simplement la méthode Class en utilisant ceci foobar->foobarfunc();


2
Veuillez ne répondre aux anciennes questions que si vous avez quelque chose de nouveau à ajouter.
Ajean
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.