Diberikan instance kelas, apakah mungkin untuk menentukan apakah mengimplementasikan antarmuka tertentu? Sejauh yang saya tahu, tidak ada fungsi bawaan untuk melakukan ini secara langsung. Opsi apa yang saya miliki (jika ada)?
interface IInterface
{
}
class TheClass implements IInterface
{
}
$cls = new TheClass();
if ($cls instanceof IInterface) {
echo "yes";
}
Anda dapat menggunakan operator "instanceof". Untuk menggunakannya, operan kiri adalah instance kelas dan operan kanan adalah antarmuka. Ini mengembalikan true jika objek mengimplementasikan antarmuka tertentu.
Sebagai therefromhere menunjukkan, Anda dapat menggunakan class_implements()
. Seperti halnya Refleksi, ini memungkinkan Anda untuk menentukan nama kelas sebagai string dan tidak memerlukan turunan dari kelas:
interface IInterface
{
}
class TheClass implements IInterface
{
}
$interfaces = class_implements('TheClass');
if (isset($interfaces['IInterface'])) {
echo "Yes!";
}
class_implements()
adalah bagian dari ekstensi SPL.
Lihat: http://php.net/manual/en/function.class-implements.php
Beberapa tes kinerja sederhana menunjukkan biaya dari setiap pendekatan:
Konstruksi objek di luar loop (100.000 iterasi) ____________________________________________ | class_implements | Refleksi | instanceOf | | ------------------ | ------------ | ------------ | | 140 ms | 290 ms | 35 ms | '--------------------------------------------' Konstruksi objek di dalam loop (100.000 iterasi) ____________________________________________ | class_implements | Refleksi | instanceOf | | ------------------ | ------------ | ------------ | | 182 ms | 340 ms | 83 ms | Pembuat murah | 431 ms | 607 ms | 338 ms | Konstruktor mahal '--------------------------------------------'
100.000 iterasi ____________________________________________ | class_implements | Refleksi | instanceOf | | ------------------ | ------------ | ------------ | | 149 ms | 295 ms | T / A | '--------------------------------------------'
Di mana __construct () yang mahal adalah:
public function __construct() {
$tmp = array(
'foo' => 'bar',
'this' => 'that'
);
$in = in_array('those', $tmp);
}
Tes-tes ini didasarkan pada kode sederhana ini .
nlaq menunjukkan bahwa instanceof
dapat digunakan untuk menguji apakah objek adalah turunan dari kelas yang mengimplementasikan antarmuka.
Tetapi instanceof
tidak membedakan antara tipe kelas dan antarmuka. Anda tidak tahu apakah objek adalah kelas yang kebetulan dipanggil IInterface
.
Anda juga dapat menggunakan API refleksi dalam PHP untuk menguji ini lebih spesifik:
$class = new ReflectionClass('TheClass');
if ($class->implementsInterface('IInterface'))
{
print "Yep!\n";
}
class_implements()
instanceof
lagi dengan aman .class_implements()
karena jelas lebih cepat untuk memanggil class_implements dan kemudian in_array, daripada membuat refleksi lengkapHanya untuk membantu pencarian di masa mendatang is_subclass_of juga merupakan varian yang baik (untuk PHP 5.3.7+):
sumber
Anda juga dapat melakukan hal berikut
Ini akan membuang kesalahan yang dapat dipulihkan jika
$objectSupposedToBeImplementing
tidak mengimplementasikanYourInterface
Antarmuka.sumber
Memperbarui
The
is_a
Fungsi yang hilang di sini sebagai alternatif.Saya melakukan beberapa tes kinerja untuk memeriksa mana dari cara yang dinyatakan adalah yang paling performan.
Hasil iterasi lebih dari 100rb
Menambahkan beberapa titik untuk benar-benar "merasakan" melihat perbedaannya.
Dihasilkan oleh ini: https://3v4l.org/8Cog7
Kesimpulan
Jika Anda memiliki objek untuk diperiksa, gunakan
instance of
seperti yang disebutkan dalam jawaban yang diterima.Jika Anda memiliki kelas untuk diperiksa, gunakan
is_a
.Bonus
Mengingat kasus yang Anda inginkan untuk instantiate kelas berdasarkan pada antarmuka yang Anda inginkan, itu lebih preformant untuk digunakan
is_a
. Hanya ada satu pengecualian - ketika konstruktor kosong.Contoh:
is_a(<className>, <interfaceName>, true);
Itu akan kembali
bool
. Parameter ketiga " allow_string " memungkinkannya untuk memeriksa nama kelas tanpa membuat instance kelas.sumber