Saya sadar itu instanceof
adalah operator dan itu is_a
adalah metode.
Apakah metode ini lebih lambat kinerjanya? Apa yang ingin Anda gunakan?
Saya sadar itu instanceof
adalah operator dan itu is_a
adalah metode.
Apakah metode ini lebih lambat kinerjanya? Apa yang ingin Anda gunakan?
Jawaban:
Memperbarui
Pada PHP 5.3.9 , fungsionalitas
is_a()
telah berubah. Jawaban asli di bawah ini menyatakan bahwais_a()
harus menerimaObject
argumen pertama, tetapi versi PHP> = 5.3.9 sekarang menerima argumen opsional boolean ketiga$allow_string
(default untukfalse
) untuk memungkinkan perbandingan nama kelas string sebagai gantinya:Perbedaan utama dalam perilaku baru antara
instanceof
danis_a()
adalah bahwainstanceof
akan selalu memeriksa bahwa target adalah objek instantiated dari kelas yang ditentukan (termasuk memperluas kelas), sedangkanis_a()
hanya mensyaratkan bahwa objek akan dipakai saat$allow_string
argumen diatur ke nilai defaultfalse
.Asli
Sebenarnya,
is_a
adalah fungsi, sedangkaninstanceof
bahasa adalah konstruksi.is_a
akan secara signifikan lebih lambat (karena memiliki semua overhead menjalankan panggilan fungsi), tetapi waktu eksekusi keseluruhan minimal dalam kedua metode.Tidak lagi usang pada 5.3, jadi tidak ada kekhawatiran di sana.
Namun ada satu perbedaan.
is_a
menjadi fungsi mengambil objek sebagai parameter 1, dan string (variabel, konstan, atau literal) sebagai parameter 2. Jadi:instanceof
mengambil objek sebagai parameter 1, dan dapat mengambil nama kelas (variabel), instance objek (variabel), atau pengidentifikasi kelas (nama kelas ditulis tanpa tanda kutip) sebagai parameter 2.sumber
is_a
pantas?$class = 'Foo'; var_dump($obj instanceof $class);
is_a
vsinstanceof
operator adalah yangis_a
akan menerima ekspresi untuk parameter kedua, sementara instance tidak akan. Misalnyais_a($object, 'Prefix_'.$name)
berfungsi sementara$object instanceof 'Prefix_'.$name
tidakis_a
seharusnya tidak pernah ditinggalkan sejak awal. Ini agak terlambat untuk memperbaikinya sekarang. Masalahnya adalah bahwainstanceof
operator melempar kesalahan sintaksis dalam PHP 4, dan karenais_a
sudah usang pada saat yang sama dengan operator diperkenalkan itu menjadi mustahil untuk menulis kode untuk PHP 4 dan 5 tanpa melemparkan E_STRICT sekitar. Anda bahkan tidak dapat melakukannyaif (version_compare(PHP_VERSION, 5) >= 0) { /* use instanceof */ } else { /* use is_a */ }
karena itu masih akan menyebabkan kesalahan sintaksis dalam PHP 4.Berikut ini adalah hasil kinerja is_a () dan instanceof :
Sumber tes ada di sini .
sumber
php 7
tidak ada perbedaan.instanceof
dapat digunakan dengan instance objek lain, nama kelas, atau antarmuka.Saya tidak berpikir itu(Pembaruan: Lihat https://gist.github.com/1455148 )is_a()
bekerja dengan antarmuka (hanya string yang mewakili nama kelas), tetapi benar jika itu benar.Contoh dari php.net :
output:
sumber
is_a
tidak bekerja dengan antarmuka dengan cara yang sama sepertiinstanceof
(saya akan mengatakan hal yang sama, tapi saya memeriksanya sebelum mengirimkan, dan itu memang berfungsi) ...Sehubungan dengan jawaban ChrisF,
is_a()
tidak lagi ditinggalkan pada PHP 5.3.0. Saya menemukan selalu lebih aman untuk menggunakan sumber resmi untuk hal-hal seperti ini.Berkenaan dengan pertanyaan Anda, Daniel, saya tidak bisa mengatakan tentang perbedaan kinerja, tetapi sebagian dari itu akan turun ke kesiapan dan yang Anda temukan lebih mudah untuk dikerjakan.
Juga, ada beberapa diskusi tentang kebingungan di sekitar meniadakan sebuah
instanceof
cek vsis_a()
. Misalnya, untukinstanceof
Anda lakukan:vs yang berikut untuk
is_a()
:atau
Sunting Sepertinya ChrisF menghapus jawabannya, tetapi bagian pertama dari jawaban saya tetap ada.
sumber
Selain kecepatan, perbedaan penting lainnya adalah bagaimana mereka menangani kasus tepi.
Jadi, is_a () menyoroti kemungkinan bug sementara instanceof menekannya.
sumber
Optimalisasi minimal. Dan optimasi mikro tidak pernah merupakan jawaban yang benar-benar bagus, di depan keterbacaan, pemahaman dan stabilitas kode.
(Secara pribadi saya lebih suka contoh , tetapi pilihan ada di tangan Anda;))
Perbedaan utama adalah kemungkinan untuk menggunakan nama kelas langsung dengan instanceof
lebih pendek dari
(ok ... itu tidak sepele.)
Warna sintaksis antara instanceof (struktur bahasa) dan is_a juga berguna (bagi saya). membiarkan warna fungsi untuk operasi yang lebih besar. Dan untuk penggunaan tunggal jika, misalnya, tidak perlu tanda kurung lagi.
Catatan: Tentu saja alih-alih kelas MyClass :: Anda dapat menggunakan string langsung yang lebih pendek:
Tetapi menggunakan string langsung dalam kode bukanlah praktik yang baik .
Kolokasi sintaksis lebih baik dan lebih berguna jika Anda dapat membuat perbedaan antara string sederhana dan nama kelas. Dan lebih mudah untuk mengubah nama dengan classname konstan. Khususnya jika Anda menggunakan namespace dengan alias.
Jadi, mengapa kita menggunakan is_a () ?
Untuk raison yang sama: keterbacaan dan undestandability. (Pilihan ada di tangan Anda) Terutama ketika digunakan dengan ! atau operator boolean lainnya: is_a tampaknya lebih praktis dengan tanda kurung.
lebih mudah dibaca daripada:
Alasan bagus lainnya adalah ketika Anda perlu menggunakan fungsi panggil balik. (seperti array_map ...) instanceof bukan fungsi, ini adalah konstruksi bahasa, jadi Anda tidak dapat menggunakannya sebagai panggilan balik.
Dalam kasus ini, is_a mungkin berguna
sumber
Saya tidak dapat berbicara untuk kinerja - saya belum mengukur apa pun - tetapi tergantung pada apa yang Anda coba, ada batasannya
instanceof
. Lihatlah pertanyaan saya, baru-baru ini, tentang hal itu:PHP 'instanceof' gagal dengan konstanta kelas
Saya akhirnya menggunakan
is_a
sebagai gantinya. Saya suka struktur yanginstanceof
lebih baik (saya pikir ini berbunyi lebih bagus) dan akan terus menggunakannya di mana saya bisa.sumber
Berikut adalah hasil kinerja yang diperoleh dari sini :
instanceof
lebih cepat.Fungsi
Waktu (masing-masing berjalan 5000 kali)
sumber
Ada skenario di mana hanya
is_a()
berfungsi daninstanceof
akan gagal.instanceof
mengharapkan nama kelas literal atau variabel yang merupakan objek atau string (dengan nama kelas) sebagai argumen yang benar.Tetapi jika Anda ingin memberikan string nama kelas dari pemanggilan fungsi, itu tidak akan berfungsi dan menghasilkan kesalahan sintaksis.
Namun, skenario yang sama berfungsi dengan baik
is_a()
.Contoh:
Ini didasarkan pada PHP 7.2.14.
sumber