Неустранимая ошибка PHP: использование $ this, когда не в контексте объекта

138

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

Я пишу новое WebApp без Framework.

В моем 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();

Почему появляется ошибка?

ahmet2106
источник
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();
Sarfraz
источник
1
Переменные с одинаковыми именами не являются проблемой. $this->fooявляется членом класса, а $fooявляется просто переменной в области видимости функции (импортированной из глобальной области видимости). Имена функций с тем же именем, что и член, также не являются проблемой.
Гордон
157
Вы не можете использовать $thisстатический метод.
Yacoby
5
Забавно, что за совершенно неправильный ответ все равно набирают голоса. $ this недоступен в контексте класса. OP получит ту же ошибку, что и в приведенном выше примере.
Гордон
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

Сначала вы понимаете одну вещь: $ this внутри класса обозначает текущий объект .
То есть вы созданы вне класса для вызова функции или переменной класса.

Поэтому, когда вы вызываете функцию своего класса, например foobar :: foobarfunc (), объект не создается. Но внутри этой функции вы написали return $ this-> foo (). Теперь здесь $ это ничего. Вот почему он говорит Использование $ this, когда не в контексте объекта в class.php

Решения:

  1. Создайте объект и вызовите foobarfunc ().

  2. Вызовите foo (), используя имя класса внутри foobarfunc ().

Рамасами Каси
источник
2
или просто используйте self :: вместо $ this
Motassem MK
4

Когда вы вызываете функцию в статическом контексте, $this просто не существует.

Вы должны использовать this::xyz() вместо этого.

Чтобы узнать, в каком контексте вы находитесь, когда функция может вызываться как статически, так и в экземпляре объекта, хороший подход изложен в следующем вопросе: как определить, статический ли я или объект?

Пекка
источник
4

Быстрый способ: (new foobar ()) -> foobarfunc ();

Вам нужно загрузить свой класс replace:

foobar::foobarfunc();

по :

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

или :

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

Или сделайте статическую функцию для использования foobar::.

class foobar {
    //...

    static function foobarfunc() {
        return $this->foo();
    }
}
A-312
источник
0

$foobar = new foobar;поместите класс foobar в $ foobar, а не объект . Чтобы получить объект, нужно добавить скобки:$foobar = new foobar();

Ваша ошибка заключается в том, что вы вызываете метод класса, поэтому его нет, $thisпоскольку он $thisсуществует только в объектах.

е-удовлетворяться
источник
0

Мне кажется, это ошибка PHP. Ошибка

'Неустранимая ошибка: Неперехваченная ошибка: использование $ this, когда не в контексте объекта в'

появляется в функции using $this, но ошибка в том, что вызывающая функция использует нестатическую функцию как статическую. То есть:

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

Пока ошибка здесь:

Class_Name::foo();
Яаков Агламаз
источник
-2

Просто используйте метод Class, используя это foobar->foobarfunc();

Манобендронат Бисвас
источник
2
Пожалуйста , только ответить на старые вопросы , если у вас есть что - то новое добавить.
Аджан