Apa perbedaan antara menggunakan self
dan static
pada contoh di bawah ini?
class Foo
{
protected static $bar = 1234;
public static function instance()
{
echo self::$bar;
echo "\n";
echo static::$bar;
}
}
Foo::instance();
menghasilkan
1234
1234
Jawaban:
Saat Anda menggunakan
self
untuk merujuk ke anggota kelas, Anda merujuk ke kelas di mana Anda menggunakan kata kunci. Dalam kasus ini,Foo
kelas Anda mendefinisikan properti statis yang dilindungi yang disebut$bar
. Saat Anda menggunakanself
diFoo
kelas untuk merujuk ke properti, Anda merujuk ke kelas yang sama.Oleh karena itu jika Anda mencoba untuk menggunakan
self::$bar
tempat lain di AndaFoo
kelas tetapi Anda memilikiBar
kelas dengan nilai yang berbeda untuk properti, itu akan menggunakanFoo::$bar
bukanBar::$bar
, yang mungkin tidak apa yang Anda berniat:Saat Anda memanggil metode lewat
static
, Anda memanggil fitur yang disebut late static bindings (diperkenalkan di PHP 5.3).Dalam skenario di atas, penggunaan
self
akan menghasilkanFoo::$bar
(1234). Dan menggunakanstatic
akan menghasilkanBar::$bar
(4321) karena withstatic
, interpreter memperhitungkan deklarasi ulang dalamBar
kelas selama runtime.Anda biasanya menggunakan binding statis terbaru untuk metode atau bahkan kelas itu sendiri, daripada properti, karena Anda tidak sering mendeklarasikan ulang properti di subkelas; contoh penggunaan
static
kata kunci untuk memanggil konstruktor terikat-akhir dapat ditemukan dalam pertanyaan terkait ini: Diri baru vs. statis baruNamun, itu juga tidak menghalangi penggunaan
static
with properti.sumber
<?php class Foo { public static $bar = 1234; public static function a( ) { echo 'static'.static::$bar; echo 'self'.self::$bar; } } class Bar extends Foo { public static $bar = 4321; } (new Bar())->a(); ?>
self::$abc
ketika digunakan diclass Foo
dalam sama dengan mengatakanFoo::$abc
. Itu tidak akan terpengaruh oleh deklarasi ulang apa pun$abc
dalam subclass. AFAIK, satu-satunya alasan penggunaanself
adalah sebagai singkatan, untuk menghindari penggunaan nama kelasFoo
, yang mungkin lebih panjang. [Ini juga berarti Anda dapat mengubah nama kelas tanpa mengubah semua tempat itu - tapi itu bukan alasan IMHO.] (Pilihan nama PHP sangat disayangkan, dan tampaknya mundur; "statis" adalah salah satu yang dapat berubah - yang mana berlawanan dengan arti sehari-hari dari kata bahasa alami "statis".)Seperti yang disebutkan, salah satu perbedaan utama adalah
static
memungkinkan binding statis terlambat. Salah satu skenario paling berguna yang saya temukan adalah untuk membuat kelas Basis untuk Kelas Singleton:Menggunakan
return static::$name
di kelas Base akan mengembalikan apa yang terpasang secara statis saat diperpanjang. Jika Anda menggunakanreturn self::$name
makaB::getName()
akan mengembalikan string kosong seperti yang dideklarasikan di kelas Base.sumber
Dengan
self
panggilan:Anda dapat melihat di atas, meskipun kita telah menimpa
$var
denganBar
kelas kita , itu tetap kembali123
, karena kita secara eksplisit memintaself
variabel PHP , yang pada gilirannya memintaFoo
variabel s sebagai gantinya.Sekarang jika kita menukar panggilan dengan
static
, kita akan mendapatkanBar
nilai yang diganti:Dengan
static
panggilan:sumber