web-dev-qa-db-fra.com

PHP Erreur fatale: utilisation de $ this en dehors du contexte de l'objet

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: utilisation de $ this lorsque le contexte de l'objet n'est pas dans class.php en ligne ... (dans cet exemple, il s'agirait de 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?

119
ahmet2106

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 une 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();
158
Sarfraz

Vous appelez une méthode non statique:

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

En utilisant un appel statique:

foobar::foobarfunc();

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

Alors :

  • Vous ne devez pas utiliser d'appels statiques pour des méthodes non statiques
  • Vos méthodes statiques (ou statiquement appelées) 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 propriété $foo 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 devriez pas utiliser d'appels statiques: vous devriez 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 méthode __construct:

global $foo;

En utilisant le global mot-clé , la variable $foo, déclarée en dehors de toutes les fonctions et classes, sera visible de l'intérieur de cette méthode ... Et vous n'avez probablement pas une telle $foo variable.

Pour accéder à $fooclass-property , il vous suffit d'utiliser $this->foo, comme vous l'avez fait.

25
Pascal MARTIN

Si vous appelez foobarfunc avec opérateur d'étendue de résolution (::), vous l'appelez de manière statique , par exemple. au niveau de la classe au lieu du niveau de l'instance, vous utilisez donc avec $this lorsque vous n'êtes pas dans le contexte de l'objet . $this n'existe pas dans le contexte de la classe.

Si vous activez E_STRICT, PHP émettra 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();

Dans le même ordre d'idées, je suggère de ne pas utiliser global dans vos classes. Si vous avez besoin de quelque chose d'extérieur à l'intérieur de votre classe, faites-le passer par le constructeur. Cela s’appelle Injection de dépendance et rendra votre code beaucoup plus facile à gérer et moins dépendant de l’extérieur.

11
Gordon

D'abord, vous comprenez une chose, $ this à l'intérieur d'une classe désigne le objet actuel.
C’est-à-dire 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 dans cette fonction, vous écrivez return $ this-> foo (). Maintenant voici $ ce n'est rien. C’est pourquoi on dit Utiliser $ this quand le contexte de l’objet n’est pas dans class.php

Solutions:

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

  2. Appelez foo () en utilisant le nom de la classe à l'intérieur de foobarfunc ().

6
Ramasamy Kasi

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

Vous devez charger votre classe, remplacez:

foobar::foobarfunc();

par :

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

ou :

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

Ou bien utilisez la fonction statique pour utiliser foobar::.

class foobar {
    //...

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

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

Vous devrez utiliser this::xyz() à la 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-je statique ou un objet?

4
Pekka 웃

$foobar = new foobar; put 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 a donc pas de $this puisque $this n'existe que dans les objets.

0
e-satis