Фатальна помилка PHP: Використання $ this, коли не в об'єктному контексті


137

У мене проблема:

Я пишу новий WebApp без рамки.

У моєму index.php я використовую:require_once('load.php');

І в load.php я використовую require_once('class.php');для завантаження class.php .

У моєму class.php у мене помилка:

Фатальна помилка: Використання $ this, коли не в об'єктному контексті в class.php в рядку ... (у цьому прикладі було б 11)

Приклад того, як написано мій 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;
    }
}

У своєму index.php я завантажую, можливо, foobarfunc()так:

foobar::foobarfunc();

але також може бути

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

Чому виникає помилка?


2
Випадково я вчора близько 3 годин боровся з цією помилкою! :)
Джек

Відповіді:


184

У своєму index.php я завантажую, можливо, foobarfunc (), як це:

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

але також може бути

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

Ви не можете викликати метод таким чином, оскільки це не статичний метод.

foobar::foobarfunc();

Натомість слід використовувати:

foobar->foobarfunc();

Якщо ви створили статичний метод на кшталт:

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

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

тоді ви можете скористатися цим:

foobar::foobarfunc();

1
Змінні, що мають однакове ім'я, не є проблемою. $this->fooє членом класу, тоді як $fooє лише змінною в області функцій (імпортовано з глобальної області). Імена функцій з тим же ім'ям, що і член, також не є проблемою.
Гордон

157
Ви не можете використовувати $thisстатичний метод.
Yacoby

5
Дивно, як все-таки абсолютно невірна відповідь отримує відгуки. $ це недоступно в контексті класу. ОП отримає таку ж помилку з наведеного вище прикладу.
Гордон

4
@Sarfraz Без образи, але все одно не так. Ви можете викликати метод екземпляра за допомогою ::. Це проти E_STRICT, але він робить роботу, поки тіло методу не посилається на сферу примірника, наприклад , використання $this. Також self::fooне вказуватимуть $this->foo. Він посилається на константу класу . І те self::fooй self::$fooінше , і призвело б до фатальної помилки.
Гордон

3
@Sarfraz зараз краще. Вибачте за те, що ви скупили, але, як це стало прийнятою відповіддю, я вважав за потрібне вказати ці речі :) Дякую за терпіння.
Гордон

27

Ви викликаєте нестатичний метод:

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

Використання статичного виклику:

foobar::foobarfunc();

При використанні статичного виклику буде викликана функція (навіть якщо вона не оголошена як static) , але, оскільки немає примірника об'єкта, немає$this .

Так :

  • Не слід використовувати статичні виклики для нестатичних методів
  • Ваші статичні методи (або статично викликані методи) не можуть використовувати $ this, що зазвичай вказує на поточний екземпляр класу, оскільки немає екземпляра класу, коли ви використовуєте статичні виклики.


Тут методи вашого класу використовують поточний екземпляр класу, оскільки вони потребують доступу до $foo властивості класу.

Це означає, що вашим методам потрібен екземпляр класу - це означає, що вони не можуть бути статичними.

Це означає, що ви не повинні використовувати статичні виклики: ви повинні інстанціювати клас та використовувати об'єкт для виклику методів, як ви робили в останній частині коду:

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


Для отримання додаткової інформації, не соромтесь прочитати, у посібнику PHP:


Також зауважте, що вам, ймовірно, не потрібен цей рядок у вашому __constructметоді:

global $foo;

Використання globalключового слова зробить $fooзмінну, оголошену поза всіма функціями та класами, видимою зсередини цього методу ... І, мабуть, у вас немає такого$foo змінної.

Для доступу до $foo властивості класу вам потрібно використовувати лише те $this->foo, що ви робили.


11

Якщо ви звертаєтесь foobarfuncдо оператора області роздільної здатності ( ::), ви викликаєте його статично , наприклад, на рівні класу замість рівня екземпляра, таким чином ви використовуєте, $thisколи не в об'єктному контексті .$thisне існує в контексті класу.

Якщо ввімкнути E_STRICT, PHP надішле повідомлення про це:

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

Зробіть це замість цього

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

Щось із боку, я пропоную не використовувати globalвсередині ваших занять. Якщо вам потрібно щось зовні всередині вашого класу, передайте це через конструктор. Це називається ін'єкцією залежностей, і це зробить ваш код набагато більш доступним та менш залежним від зовнішніх речей.


6

Спочатку ви зрозумієте одне, $ це всередині класу позначає поточний об'єкт .
Тобто це те, що ви створені поза класом для виклику функції класу або змінної.

Отже, коли ви викликаєте функцію класу на зразок foobar :: foobarfunc (), об'єкт не створюється. Але всередині цієї функції ви написали return $ this-> foo (). Тепер ось $ це нічого. Ось чому його вислів Використовуючи $ this, коли не в об'єктному контексті у class.php

Рішення:

  1. Створіть об’єкт та зателефонуйте до foobarfunc ().

  2. Викличте foo (), використовуючи назву класу всередині foobarfunc ().


2
або просто використовуйте self :: замість $ this
Motassem MK

4

Коли ви викликаєте функцію в статичному контексті, її $thisпросто не існує.

Вам доведеться використовувати this::xyz()замість цього.

Щоб дізнатися, в якому контексті ви знаходитесь, коли функцію можна викликати як статично, так і в об'єктному екземплярі, у цьому питанні викладено хороший підхід: Як сказати, я статичний чи об'єкт?


4

Швидкий метод: (новий foobar ()) -> foobarfunc ();

Вам потрібно завантажити заміну класу:

foobar::foobarfunc();

автор:

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

або:

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

Або зробити статичну функцію для використання foobar::.

class foobar {
    //...

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

0

$foobar = new foobar;помістіть клас foobar в $ foobar, а не об'єкт . Щоб отримати об’єкт, вам потрібно додати дужки:$foobar = new foobar();

Ваша помилка полягає лише в тому, що ви викликаєте метод на класі, тому його немає, $thisоскільки $thisіснує лише в об'єктах.


0

Мені здається, це помилка в PHP. Помилка

'Fatal error: Uncaught Error: Використання $ this, коли не в об'єктному контексті в'

з'являється у функції з використанням $this, але помилка полягає в тому, що функція виклику використовує нестатичну функцію як статичну. Тобто:

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

Поки помилка тут:

Class_Name::foo();

-2

Просто використовуйте метод Class, використовуючи цей foobar->foobarfunc();


2
Будь ласка, відповідайте лише на старі запитання, якщо у вас є щось нове .
Ajean
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.