Apa self baru (); berarti di PHP?

110

Saya belum pernah melihat kode seperti ini:

public static function getInstance()
{
    if ( ! isset(self::$_instance)) {
        self::$_instance = new self();
    }
    return self::$_instance;
}

Apakah itu sama dengan new className()?

EDIT

Jika kelas tersebut diturunkan, kelas mana yang ditunjuknya?

pengguna198729
sumber
@ Stereofrog, maksud Anda pola tunggal harus ditinggalkan? Tapi semua hal ada karena suatu alasan, bukan?
pengguna198729
Oh, saya cenderung setuju dengan poin ini: singleton harus diganti dengan pabrik
user198729
@stereofrog Singleton adalah racun bagi pengujian unit, sangat sulit untuk membuat pengujian yang tidak dapat diubah pada sesuatu yang mengubah status dari satu panggilan ke panggilan berikutnya.
David
Sayangnya, metode ini tidak akan diperpanjang. Ini akan selalu memberi Anda objek baru dari kelas tempat fungsi ini didefinisikan.
Ares

Jawaban:

211

self menunjuk ke kelas di mana itu ditulis.

Jadi, jika metode getInstance Anda ada dalam nama kelas MyClass, baris berikut:

self::$_instance = new self();

Akan melakukan hal yang sama seperti:

self::$_instance = new MyClass();



Edit: beberapa informasi lagi, setelah komentar.

Jika Anda memiliki dua kelas yang saling memperluas, Anda memiliki dua situasi:

  • getInstance didefinisikan di kelas anak
  • getInstance didefinisikan di kelas induk

Situasi pertama akan terlihat seperti ini (saya telah menghapus semua kode yang tidak diperlukan, untuk contoh ini - Anda harus menambahkannya kembali untuk mendapatkan perilaku tunggal) *:

class MyParentClass {

}
class MyChildClass extends MyParentClass {
    public static function getInstance() {
        return new self();
    }
}

$a = MyChildClass::getInstance();
var_dump($a);

Di sini, Anda akan mendapatkan:

object(MyChildClass)#1 (0) { } 

Yang artinya selfberarti MyChildClass- yaitu kelas di mana itu ditulis.


Untuk situasi kedua, kodenya akan terlihat seperti ini:

class MyParentClass {
    public static function getInstance() {
        return new self();
    }
}
class MyChildClass extends MyParentClass {

}

$a = MyChildClass::getInstance();
var_dump($a);

Dan Anda akan mendapatkan hasil seperti ini:

object(MyParentClass)#1 (0) { }

Yang berarti selfberarti MyParentClass- yaitu sini juga, kelas di mana ada tertulis .




Dengan PHP <5.3, "kelas tempat ia ditulis" itu penting - dan terkadang dapat menyebabkan masalah.

Itulah mengapa PHP 5.3 memperkenalkan penggunaan baru untuk statickata kunci: sekarang dapat digunakan tepat di tempat yang kita gunakan selfdalam contoh tersebut:

class MyParentClass {
    public static function getInstance() {
        return new static();
    }
}
class MyChildClass extends MyParentClass {

}

$a = MyChildClass::getInstance();
var_dump($a);

Namun, dengan staticalih - alih self, Anda sekarang akan mendapatkan:

object(MyChildClass)#1 (0) { } 

Yang berarti staticpoin semacam itu ke kelas yang digunakan (yang kami gunakan MyChildClass::getInstance()), dan bukan yang tertulis.

Tentu saja, perilaku selfbelum diubah, untuk tidak merusak aplikasi yang ada - PHP 5.3 baru saja menambahkan perilaku baru, mendaur ulang statickata kunci.


Dan, berbicara tentang PHP 5.3, Anda mungkin ingin melihat halaman Binding Statis Akhir dari manual PHP.

Pascal MARTIN
sumber
@Paul: heu ... berarti "diri bertindak sebagai alias ke", atau "semacam poin sendiri ke" - kata kerja "desainer", dalam bahasa Prancis, dapat digunakan untuk itu - Saya kira itu salah satu situasinya di mana menggunakan kata yang sama dalam bahasa Inggris bukanlah ide yang baik ;-( Saya akan mengedit jawaban saya untuk memperbaikinya ;; terima kasih :-)
Pascal MARTIN
Bagaimana jika ada baseclass, classyang satu tidak menunjuk ke?
pengguna198729
@ pengguna: Saya telah mengedit jawaban saya untuk memberikan lebih banyak informasi tentang selfdan warisan; dan saya juga menyertakan beberapa informasi tentang staticdi PHP 5.3 ;; harap ini membantu :-)
Pascal MARTIN
10

Ini tampaknya merupakan implementasi dari pola Singleton . Fungsi ini dipanggil secara statis dan memeriksa apakah kelas statis memiliki $_instanceset variabel .

Jika tidak, itu menginisialisasi sebuah instance dari dirinya sendiri ( new self()) dan menyimpannya di $_instance.

Jika Anda menelepon, className::getInstance()Anda akan mendapatkan satu dan instance kelas yang sama pada setiap panggilan, yang merupakan titik pola singleton.

Saya belum pernah melihat ini dilakukan dengan cara ini, dan sejujurnya tidak tahu itu mungkin. Apa yang $_instancedideklarasikan di kelas?

Pekka
sumber
1
$_instancedideklarasikan sebagaipublic static $_instance;
Atif
7

Ini kemungkinan besar digunakan dalam pola desain tunggal, di mana konstruktor didefinisikan sebagai privat untuk menghindari pembuatan instance, (::)operator titik dua ganda dapat mengakses anggota yang dinyatakan statis di dalam kelas, jadi jika ada anggota statis, variabel pseudo $ ini tidak dapat digunakan, oleh karena itu kodenya digunakan sendiri, Singletons adalah praktik pemrograman yang baik yang hanya akan mengizinkan 1 instance objek seperti penangan konektor database. Dari kode klien, mengakses instance itu akan dilakukan dengan membuat satu titik akses, dalam hal ini dia menamakannya getInstance(), getInstance itu sendiri adalah fungsi yang membuat objek pada dasarnya menggunakan kata kunci baru untuk membuat objek yang berarti metode konstruktor itu disebut juga.

baris ini if(!isset(self::instance))memeriksa apakah suatu objek telah dibuat, Anda tidak dapat memahami ini karena kodenya hanyalah sebuah fragmen, di suatu tempat di atas, harus ada anggota statis seperti mungkin

private static $_instance = NULL; 

di kelas normal kami akan mengakses anggota ini dengan mudah

$this->_instance = 'something';

tetapi ini dinyatakan statis sehingga kami tidak dapat menggunakan $ kode ini yang kami gunakan sebagai gantinya

self::$_instance

dengan memeriksa apakah ada objek yang disimpan pada variabel kelas statis ini, kelas kemudian dapat memutuskan untuk membuat atau tidak membuat satu instance, jadi jika tidak disetel,! isset, artinya tidak ada objek pada anggota statis $ _instance, maka itu menghasilkan objek baru, menyimpannya di anggota statis $_instancedengan perintah

self::$_instance = new self();

dan mengembalikannya ke kode klien. Kode klien kemudian dapat dengan senang hati menggunakan contoh tunggal objek dengan metode publiknya, tetapi dalam kode klien, memanggil titik akses tunggal, yaitu, getInstance()metode ini juga rumit, harus dipanggil seperti ini

$thisObject = className::getInstance();

Pasalnya, fungsi itu sendiri dinyatakan statis.

flimh
sumber
2

Ya, ini seperti new className()(mengacu pada kelas yang berisi metode itu), mungkin digunakan dalam pola Singleton di mana konstruktornya bersifat pribadi.

Matteo Riva
sumber
Mengapa seseorang menggunakan pola Singleton di PHP? Kecuali digunakan dalam program mirip daemon, singleton hanya akan hidup saat skrip berjalan dan kemudian menghilang bersama program.
ILikeTacos
4
untuk menghindari secara menjengkelkan mendeklarasikan global untuk mengakses variabel global
Sam Adamsh
0

Jika kelas diwarisi maka memanggil getInstance () dari anak tidak akan memberi Anda instance anak. Ini hanya akan mengembalikan instance dari instance induk. Ini karena kita menyebut diri baru ().

Jika Anda ingin agar kelas anak akan mengembalikan turunan dari kelas anak kemudian gunakan static () baru di getInstance () dan kemudian akan mengembalikan contoh kelas anak. Ini disebut pengikatan terlambat !!

kta
sumber