PHP Fatal error: Menggunakan $ this saat tidak dalam konteks objek

137

Saya punya masalah:

Saya sedang menulis WebApp baru tanpa Framework.

Di index.php saya, saya menggunakan:require_once('load.php');

Dan di load.php yang saya gunakan require_once('class.php');untuk memuat class.php saya .

Di class.php saya saya punya kesalahan ini:

Kesalahan fatal: Menggunakan $ this ketika tidak dalam konteks objek di class.php on line ... (dalam contoh ini akan menjadi 11)

Contoh bagaimana class.php saya ditulis:

class foobar {

    public $foo;

    public function __construct() {
        global $foo;

        $this->foo = $foo;
    }

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

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

Di index.php saya, saya memuat mungkin foobarfunc()seperti ini:

foobar::foobarfunc();

tapi bisa juga

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

Mengapa ada kesalahan?

ahmet2106
sumber
2
Kebetulan saya berjuang dengan kesalahan ini selama sekitar 3 jam kemarin! :)
Jack

Jawaban:

184

Di index.php saya, saya memuat mungkin foobarfunc () seperti ini:

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

tapi bisa juga

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

Anda tidak dapat memanggil metode dengan cara ini karena ini bukan metode statis.

foobar::foobarfunc();

Anda sebaiknya menggunakan:

foobar->foobarfunc();

Namun jika Anda telah membuat sesuatu metode statis seperti:

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

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

maka Anda dapat menggunakan ini:

foobar::foobarfunc();
Sarfraz
sumber
1
Variabel yang memiliki nama yang sama tidak menjadi masalah. $this->fooadalah anggota kelas, sementara $fooitu hanya variabel dalam lingkup fungsi (diimpor dari lingkup global). Nama fungsi dengan nama yang sama dengan anggota juga tidak menjadi masalah.
Gordon
157
Anda tidak dapat menggunakan $thismetode statis.
Yacoby
5
Sungguh lucu bagaimana jawaban yang benar-benar salah terangkat. $ this tidak tersedia dalam konteks kelas. OP akan mendapatkan kesalahan yang sama dari contoh di atas.
Gordon
4
@Sarfraz Jangan tersinggung, tapi itu masih salah. Anda dapat memanggil metode instance dengan ::. Hal ini melawan E_STRICT, tapi tidak bekerja selama metode tubuh tidak referensi lingkup contoh, misalnya penggunaan $this. Juga, self::footidak akan menunjuk ke $this->foo. Itu referensi kelas konstan . Keduanya, self::foodan self::$fooakan meningkatkan Kesalahan Fatal.
Gordon
3
@Sarfraz lebih baik sekarang. Maaf telah mengganggu Anda, tetapi karena ini menjadi jawaban yang diterima, saya merasa perlu untuk menunjukkan hal-hal ini :) Terima kasih atas kesabaran Anda.
Gordon
27

Anda memanggil metode non-statis:

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

Menggunakan panggilan statis:

foobar::foobarfunc();

Saat menggunakan panggilan statis, fungsi akan dipanggil (bahkan jika tidak dinyatakan sebagai static) , tetapi, karena tidak ada turunan dari suatu objek, tidak ada $this.

Jadi:

  • Anda tidak boleh menggunakan panggilan statis untuk metode non-statis
  • Metode statis Anda (atau metode yang disebut secara statis) tidak dapat menggunakan $ this, yang biasanya menunjuk ke instance kelas saat ini, karena tidak ada instance kelas ketika Anda menggunakan panggilan statis.


Di sini, metode kelas Anda menggunakan instance kelas saat ini, karena mereka perlu mengakses $fooproperti kelas.

Ini berarti metode Anda memerlukan turunan kelas - yang berarti mereka tidak boleh statis.

Ini berarti Anda tidak boleh menggunakan panggilan statis: Anda harus membuat instance kelas, dan menggunakan objek untuk memanggil metode, seperti yang Anda lakukan di bagian kode terakhir:

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


Untuk informasi lebih lanjut, jangan ragu membaca, dalam manual PHP:


Perhatikan juga bahwa Anda mungkin tidak memerlukan baris ini dalam __constructmetode Anda :

global $foo;

Menggunakan globalkata kunci akan membuat $foovariabel, dideklarasikan di luar semua fungsi dan kelas, terlihat dari dalam metode itu ... Dan Anda mungkin tidak memiliki $foovariabel seperti itu .

Untuk mengakses $foo properti kelas , Anda hanya perlu menggunakan $this->foo, seperti yang Anda lakukan.

Pascal MARTIN
sumber
11

Jika Anda memohon foobarfuncdengan Operator lingkup resolusi ( ::), maka Anda menyebutnya statis , misalnya pada tingkat kelas, bukan tingkat misalnya, sehingga Anda menggunakan $thisketika tidak dalam konteks objek . $thistidak ada dalam konteks kelas.

Jika Anda mengaktifkan E_STRICT, PHP akan memunculkan Pemberitahuan tentang ini:

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

Lakukan ini sebagai gantinya

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

Pada sidenote, saya sarankan untuk tidak menggunakan globaldi dalam kelas Anda. Jika Anda membutuhkan sesuatu dari luar kelas Anda, sampaikan melalui konstruktor. Ini disebut Dependency Injection dan itu akan membuat kode Anda lebih mudah dirawat dan kurang bergantung pada hal-hal luar.

Gordon
sumber
6

Pertama Anda mengerti satu hal, $ this di dalam kelas menunjukkan objek saat ini .
Itulah yang Anda buat di luar kelas untuk memanggil fungsi atau variabel kelas.

Jadi ketika Anda memanggil fungsi kelas Anda seperti foobar :: foobarfunc (), objek tidak dibuat. Tetapi di dalam fungsi itu Anda menulis pengembalian $ this-> foo (). Sekarang di sini $ ini bukan apa-apa. Itulah sebabnya katanya Menggunakan $ this ketika tidak dalam konteks objek di class.php

Solusi:

  1. Buat objek dan panggil foobarfunc ().

  2. Panggil foo () menggunakan nama kelas di dalam foobarfunc ().

Ramasamy Kasi
sumber
2
atau cukup gunakan self :: bukan $ this
Motassem MK
4

Ketika Anda memanggil fungsi dalam konteks statis, $thissama sekali tidak ada.

Anda harus menggunakannya this::xyz()sebagai gantinya.

Untuk mengetahui konteks apa yang Anda hadapi ketika suatu fungsi dapat dipanggil secara statis dan dalam instance objek, pendekatan yang baik dijelaskan dalam pertanyaan ini: Bagaimana cara mengetahui apakah saya statis atau objek?

Pekka
sumber
4

Metode cepat: (foobar baru ()) -> foobarfunc ();

Anda perlu memuat ganti kelas Anda:

foobar::foobarfunc();

oleh :

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

atau :

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

Atau buat fungsi statis untuk digunakan foobar::.

class foobar {
    //...

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

$foobar = new foobar;menempatkan foobar kelas dalam $ foobar, bukan objek . Untuk mendapatkan objek, Anda perlu menambahkan tanda kurung:$foobar = new foobar();

Kesalahan Anda hanya karena Anda memanggil metode pada kelas, jadi tidak ada $thiskarena $thishanya ada di objek.

e-satis
sumber
0

Sepertinya saya menjadi bug di PHP. Kesalahannya

'Kesalahan fatal: Kesalahan Tidak Berhasil: Menggunakan $ this saat tidak dalam konteks objek di'

muncul di fungsi menggunakan $this, tetapi kesalahannya adalah bahwa fungsi panggilan menggunakan fungsi non-statis sebagai statis. Yaitu:

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

Sementara kesalahan ada di sini:

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

Cukup gunakan metode Kelas menggunakan ini foobar->foobarfunc();

Manobendronath Biswas
sumber
2
Harap hanya jawab pertanyaan lama jika Anda memiliki sesuatu yang baru untuk ditambahkan.
Ajean