memanggil metode statis di dalam kelas?

166

bagaimana saya memanggil metode statis dari metode lain di dalam kelas yang sama?

$this->staticMethod();

atau

$this::staticMethod();
ajsie
sumber
13
Anda mungkin tertarik dengan ini ( selfvs. $this): stackoverflow.com/questions/151969/php-self-vs-this
Felix Kling
Hanya FYI, contoh pertama Anda adalah variabel instan yang memanggil metode statis yang tidak mungkin karena metode statis adalah bagian dari kelas dan tidak dapat diakses melalui variabel instan.
joejoeson
Anda dapat menghapus $ this sekarang, harap tidak berfungsi jika hanya menggunakan metode statis dan tidak ada instance.
Malhal

Jawaban:

321
self::staticMethod();

Informasi lebih lanjut tentang kata kunci statis.

jeroen
sumber
...tapi kenapa? $ this-> staticMethod () berfungsi juga. Bisakah Anda jelaskan mengapa self :: staticMethod () lebih benar (jika ya)?
Ian Dunn
29
@Ian Dunn Sederhananya, $thishanya ada jika objek telah dipakai dan Anda hanya dapat menggunakan $this->methoddari dalam objek yang sudah ada. Jika Anda tidak memiliki objek selain memanggil metode statis dan dalam metode itu Anda ingin memanggil metode statis lain di kelas yang sama, Anda harus menggunakan self::. Jadi untuk menghindari kesalahan potensial (dan peringatan ketat) lebih baik digunakan self.
jeroen
1
Terima kasih! Dalam laravel, saya menemukan bahwa saya secara tidak sengaja memanggil metode statis menggunakan pengontrol yang diperluas $this, tetapi masalah tidak muncul sampai kode didorong ke stage. tidak ada kesalahan kembali, nilainya adil 0. hati-hati dengan ini, gunakanself::
blamb
44

Anggap ini kelas Anda:

class Test
{
    private $baz = 1;

    public function foo() { ... }

    public function bar() 
    {
        printf("baz = %d\n", $this->baz);
    }

    public static function staticMethod() { echo "static method\n"; }
}

Dari dalam foo()metode, mari kita lihat opsi yang berbeda:

$this->staticMethod();

Jadi itu panggilan staticMethod()sebagai metode instan, kan? Itu tidak. Ini karena metode ini dinyatakan sebagai public staticinterpreter akan menyebutnya sebagai metode statis, sehingga akan berfungsi seperti yang diharapkan. Dapat diperdebatkan bahwa hal itu membuatnya kurang jelas dari kode bahwa panggilan metode statis sedang berlangsung.

$this::staticMethod();

Karena PHP 5.3 bisa Anda gunakan $var::method()dengan maksud <class-of-$var>::; ini cukup nyaman, meskipun use-case di atas masih sangat tidak konvensional. Jadi itu membawa kita ke cara paling umum memanggil metode statis:

self::staticMethod();

Sekarang, sebelum Anda mulai berpikir bahwa ::adalah yang operator yang statis panggilan, biarkan saya memberikan contoh lain:

self::bar();

Ini akan mencetak baz = 1, yang berarti $this->bar()dan self::bar()melakukan hal yang persis sama; itu karena ::hanya operator resolusi lingkup. Itu ada di sana untuk membuat parent::, self::dan static::bekerja dan memberi Anda akses ke variabel statis; bagaimana suatu metode dipanggil tergantung pada tanda tangannya dan bagaimana penelepon dipanggil.

Untuk melihat semua ini dalam tindakan, lihat output 3v4l.org ini .

Mendongkrak
sumber
self::bar()tampaknya menyesatkan - apakah itu sudah usang? (gunakan self::untuk memanggil metode contoh daripada metode statis).
ToolmakerSteve
@ToolmakerSteve dengan cara apa Anda akan mengatakan bahwa itu menyesatkan?
Ja͢ck
Berbicara secara logis, tidak ada selfketika memohon metode statis. Menurut definisi: metode statis dapat dipanggil dari mana saja, dan tidak menerima parameter "mandiri". Meskipun demikian, saya melihat kemudahan phpsintaks itu, sehingga Anda tidak perlu menulis MyClassName::. Saya terbiasa dengan bahasa yang diketik secara statis, di mana kompiler harus diberi semua variabel yang tersedia dalam lingkup saat ini, sehingga (setara dengan) self::dapat dihilangkan. Jadi seseorang hanya berkata self instanceMethod; tidak ada alasan untuk mengatakan self staticMethod.
ToolmakerSteve
15

Ini adalah respons yang sangat terlambat, tetapi menambahkan beberapa detail pada jawaban sebelumnya

Ketika datang untuk memanggil metode statis di PHP dari metode statis lain di kelas yang sama, penting untuk membedakan antara selfdan nama kelas.

Ambil contoh kode ini:

class static_test_class {
    public static function test() {
        echo "Original class\n";
    }

    public static function run($use_self) {
        if($use_self) {
            self::test();
        } else {
            $class = get_called_class();
            $class::test(); 
        }
    }
}

class extended_static_test_class extends static_test_class {
    public static function test() {
        echo "Extended class\n";
    }
}

extended_static_test_class::run(true);
extended_static_test_class::run(false);

Output dari kode ini adalah:

Kelas asli

Kelas yang diperluas

Ini karena selfmerujuk ke kelas kode itu, bukan kelas kode itu dipanggil.

Jika Anda ingin menggunakan metode yang didefinisikan pada kelas yang mewarisi kelas asli, Anda perlu menggunakan sesuatu seperti:

$class = get_called_class();
$class::function_name(); 
Joundill
sumber
2
Saya menemukan ini informatif. Sedikit nit, saya tidak akan mengatakan bahwa jawaban lain adalah "menyesatkan". Lebih akurat untuk mengatakan bahwa mereka "tidak lengkap"; mereka tidak menjawab pertanyaan (tanpa diminta) tentang apa yang self::terjadi pada kasus (jarang) di mana metode statis A memanggil metode statis lain B, dan B telah ditimpa dalam subkelas. IMHO, itu kurang membingungkan untuk membatasi metode menimpa metode "instance"; gunakan kemampuan itu dengan hemat pada level statis. Dengan kata lain, pembaca kode Anda mengharapkan metode yang menggantikan metode instance (yang merupakan inti dari pengkodean OO), tetapi bukan yang statis.
ToolmakerSteve
1
Sangat membantu dan masuk akal bahwa perluasan kelas bukan kelas asli. Oleh karena itu masuk akal bahwa selftidak akan digunakan dalam kasus itu. Anda telah mendeklarasikan kelas terpisah sebagai ekstensi ke kelas pertama. Menggunakan selfdalam kelas yang diperluas akan merujuk ke kelas yang diperluas. Ini tidak bertentangan dengan jawaban lain, tetapi tentu saja membantu menunjukkan ruang lingkup self.
iyrin
2

Dalam versi PHP nanti self::staticMethod();juga tidak akan berfungsi. Ini akan membuang kesalahan standar yang ketat.

Dalam hal ini, kita dapat membuat objek dengan kelas yang sama dan memanggil dengan objek

di sini adalah contohnya

class Foo {

    public function fun1() {
        echo 'non-static';   
    }

    public static function fun2() {
        echo (new self)->fun1();
    }
}
Nishad Up
sumber
Anda bisa melakukan itu, meskipun jika fun1tidak digunakan self, itu tidak logis untuk menjadikannya metode instan. Cara yang tepat untuk melakukan hal ini dalam php adalah untuk menyatakan public static function fun1, kemudian memanggil dengan menentukan kelas: Foo::fun1. Saya yakin itu adalah cara yang dimaksudkan untuk memperbaiki kesalahan standar yang ketat itu.
ToolmakerSteve