รับอินสแตนซ์ของคลาสเป็นไปได้ไหมที่จะพิจารณาว่าใช้อินเทอร์เฟซเฉพาะหรือไม่ เท่าที่ฉันรู้ไม่มีฟังก์ชั่นในตัวที่จะทำสิ่งนี้โดยตรง ฉันมีตัวเลือกอะไรบ้าง (ถ้ามี)
รับอินสแตนซ์ของคลาสเป็นไปได้ไหมที่จะพิจารณาว่าใช้อินเทอร์เฟซเฉพาะหรือไม่ เท่าที่ฉันรู้ไม่มีฟังก์ชั่นในตัวที่จะทำสิ่งนี้โดยตรง ฉันมีตัวเลือกอะไรบ้าง (ถ้ามี)
คำตอบ:
interface IInterface
{
}
class TheClass implements IInterface
{
}
$cls = new TheClass();
if ($cls instanceof IInterface) {
echo "yes";
}
คุณสามารถใช้โอเปอเรเตอร์ "instanceof" ในการใช้งานตัวถูกดำเนินการด้านซ้ายเป็นอินสแตนซ์ของคลาสและตัวถูกดำเนินการด้านขวาเป็นอินเทอร์เฟซ มันจะส่งกลับจริงถ้าวัตถุใช้อินเตอร์เฟซที่เฉพาะเจาะจง
ในฐานะที่เป็นtherefromhereclass_implements()
ชี้ให้คุณสามารถใช้ เช่นเดียวกับ Reflection สิ่งนี้อนุญาตให้คุณระบุชื่อคลาสเป็นสตริงและไม่ต้องการอินสแตนซ์ของคลาส:
interface IInterface
{
}
class TheClass implements IInterface
{
}
$interfaces = class_implements('TheClass');
if (isset($interfaces['IInterface'])) {
echo "Yes!";
}
class_implements()
เป็นส่วนหนึ่งของส่วนขยาย SPL
ดู: http://php.net/manual/th/function.class-implements.php
การทดสอบประสิทธิภาพอย่างง่าย ๆ แสดงค่าใช้จ่ายของแต่ละวิธี:
การสร้างวัตถุนอกลูป (100,000 ซ้ำ) ____________________________________________ | class_implements | ภาพสะท้อน instanceOf | | ------------------ | ------------ | ------------ | | 140 ms | 290 ms | 35 ms | '--------------------------------------------' การสร้างวัตถุภายในลูป (100,000 ซ้ำ) ____________________________________________ | class_implements | ภาพสะท้อน instanceOf | | ------------------ | ------------ | ------------ | | 182 ms | 340 ms 83 ms | ตัวสร้างราคาถูก | 431 ms | 607 ms | 338 ms | ตัวสร้างแพง '--------------------------------------------'
100,000 ซ้ำ ____________________________________________ | class_implements | ภาพสะท้อน instanceOf | | ------------------ | ------------ | ------------ | | 149 ms | 295 ms | N / A | '--------------------------------------------'
ที่ __ โครงสร้าง () ราคาแพงคือ:
public function __construct() {
$tmp = array(
'foo' => 'bar',
'this' => 'that'
);
$in = in_array('those', $tmp);
}
การทดสอบเหล่านี้ใช้รหัสง่าย ๆนี้
nlaq ชี้ให้เห็นว่าinstanceof
สามารถใช้เพื่อทดสอบว่าวัตถุนั้นเป็นอินสแตนซ์ของคลาสที่ใช้อินเทอร์เฟซ
แต่instanceof
ไม่แยกความแตกต่างระหว่างประเภทคลาสและส่วนต่อประสาน คุณไม่รู้ว่าวัตถุนั้นเป็นคลาสที่เกิดขึ้นถูกเรียกIInterface
หรือไม่
คุณยังสามารถใช้การสะท้อน API ใน PHP เพื่อทดสอบสิ่งนี้โดยเฉพาะ:
$class = new ReflectionClass('TheClass');
if ($class->implementsInterface('IInterface'))
{
print "Yep!\n";
}
class_implements()
instanceof
อีกครั้งได้อย่างปลอดภัย
class_implements()
เนื่องจากเห็นได้ชัดว่าเร็วกว่าที่จะเรียก class_implements จากนั้น in_array แทนที่จะทำการสะท้อนที่สมบูรณ์
เพียงเพื่อช่วยให้การค้นหาในอนาคตis_subclass_ofเป็นตัวแปรที่ดี (สำหรับ PHP 5.3.7+):
if (is_subclass_of($my_class_instance, 'ISomeInterfaceName')){
echo 'I can do it!';
}
คุณยังสามารถทำสิ่งต่อไปนี้
public function yourMethod(YourInterface $objectSupposedToBeImplementing) {
//.....
}
มันจะโยนข้อผิดพลาดที่กู้คืนได้หาก$objectSupposedToBeImplementing
ไม่ได้ใช้YourInterface
อินเทอร์เฟซ
is_a
ฟังก์ชั่นที่ขาดหายไปที่นี่เป็นทางเลือก
ฉันทำการทดสอบประสิทธิภาพเพื่อตรวจสอบว่าวิธีใดที่มีประสิทธิภาพมากที่สุด
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% | ............................................
เพิ่มจุดบางจุดเพื่อ "รู้สึก" จริง ๆ เห็นความแตกต่าง
สร้างโดยสิ่งนี้: https://3v4l.org/8Cog7
ในกรณีที่คุณมีวัตถุที่จะตรวจสอบการใช้งานinstance of
ดังกล่าวในคำตอบที่ได้รับการยอมรับ
ในกรณีที่คุณมีระดับis_a
การตรวจสอบการใช้งาน
ได้รับกรณีที่คุณต้องการที่จะยกตัวอย่างชั้นเรียนขึ้นอยู่กับอินเตอร์เฟซที่คุณต้องการที่จะมีก็เป็น preformant is_a
มากขึ้นในการใช้งาน มีข้อยกเว้นเพียงข้อเดียวเท่านั้น - เมื่อตัวสร้างว่างเปล่า
ตัวอย่าง:
is_a(<className>, <interfaceName>, true);
bool
มันจะกลับมา พารามิเตอร์ที่สาม " allow_string " อนุญาตให้ตรวจสอบชื่อคลาสโดยไม่สร้างอินสแตนซ์ของคลาส