Câu trả lời:
interface IInterface
{
}
class TheClass implements IInterface
{
}
$cls = new TheClass();
if ($cls instanceof IInterface) {
echo "yes";
}
Bạn có thể sử dụng toán tử "instanceof". Để sử dụng nó, toán hạng bên trái là một thể hiện của lớp và toán hạng bên phải là một giao diện. Nó trả về true nếu đối tượng thực hiện một giao diện cụ thể.
Như therefromhere chỉ ra, bạn có thể sử dụng class_implements()
. Cũng giống như với Reflection, điều này cho phép bạn chỉ định tên lớp là một chuỗi và không yêu cầu một thể hiện của lớp:
interface IInterface
{
}
class TheClass implements IInterface
{
}
$interfaces = class_implements('TheClass');
if (isset($interfaces['IInterface'])) {
echo "Yes!";
}
class_implements()
là một phần của phần mở rộng SPL.
Xem: http://php.net/manual/en/feft.group-implements.php
Một số thử nghiệm hiệu suất đơn giản cho thấy chi phí của từng phương pháp:
Xây dựng đối tượng bên ngoài vòng lặp (100.000 lần lặp) Giới thiệu | class_implements | Phản ánh | dụOf | | ------------------ | ------------ | ------------ | | 140 ms | 290 ms | 35 ms | '--------------------------------------------' Xây dựng đối tượng bên trong vòng lặp (100.000 lần lặp) Giới thiệu | class_implements | Phản ánh | dụOf | | ------------------ | ------------ | ------------ | | 182 ms | 340 ms | 83 ms | Xây dựng giá rẻ | 431 ms | 607 ms | 338 ms | Xây dựng đắt tiền '--------------------------------------------'
100.000 lần lặp Giới thiệu | class_implements | Phản ánh | dụOf | | ------------------ | ------------ | ------------ | | 149 ms | 295 ms | Không có | '--------------------------------------------'
Trong đó __construct () đắt tiền là:
public function __construct() {
$tmp = array(
'foo' => 'bar',
'this' => 'that'
);
$in = in_array('those', $tmp);
}
Các xét nghiệm này dựa trên mã đơn giản này .
nlaq chỉ ra rằng instanceof
có thể được sử dụng để kiểm tra nếu đối tượng là một thể hiện của một lớp thực hiện một giao diện.
Nhưng instanceof
không phân biệt giữa một loại lớp và một giao diện. Bạn không biết nếu đối tượng là một lớp tình cờ được gọi IInterface
.
Bạn cũng có thể sử dụng API phản chiếu trong PHP để kiểm tra điều này cụ thể hơn:
$class = new ReflectionClass('TheClass');
if ($class->implementsInterface('IInterface'))
{
print "Yep!\n";
}
class_implements()
instanceof
lại một cách an toàn .
class_implements()
vì rõ ràng nhanh hơn để gọi class_implements và sau đó là in_array, thay vì thực hiện một phản ánh hoàn chỉnh
Chỉ để giúp các tìm kiếm trong tương lai is_subgroup_of cũng là một biến thể tốt (đối với PHP 5.3.7+):
if (is_subclass_of($my_class_instance, 'ISomeInterfaceName')){
echo 'I can do it!';
}
Các is_a
chức năng bị thiếu ở đây là thay thế.
Tôi đã thực hiện một số bài kiểm tra hiệu suất để kiểm tra xem những cách nào được nêu là hiệu quả nhất.
instanceof [object] took 7.67 ms | + 0% | ..........
is_a [object] took 12.30 ms | + 60% | ................
is_a [class] took 17.43 ms | +127% | ......................
class_implements [object] took 28.37 ms | +270% | ....................................
reflection [class] took 34.17 ms | +346% | ............................................
Đã thêm một số dấu chấm để thực sự "cảm thấy" thấy sự khác biệt.
Được tạo bởi điều này: https://3v4l.org/8Cog7
Trong trường hợp bạn có một đối tượng để kiểm tra, hãy sử dụng instance of
như được đề cập trong câu trả lời được chấp nhận.
Trong trường hợp bạn có một lớp để kiểm tra, sử dụng is_a
.
Với trường hợp bạn muốn khởi tạo một lớp dựa trên một giao diện mà bạn yêu cầu nó phải có, nó sẽ được sử dụng nhiều hơn is_a
. Chỉ có một ngoại lệ - khi hàm tạo trống.
Thí dụ:
is_a(<className>, <interfaceName>, true);
Nó sẽ trở lại bool
. Tham số thứ ba " allow_ chuỗi " cho phép nó kiểm tra tên lớp mà không cần khởi tạo lớp.