อัปเดต : ขณะนี้ PHP 7.4 รองรับความแปรปรวนร่วมและความแตกต่างซึ่งแก้ไขปัญหาสำคัญที่เกิดขึ้นในคำถามนี้
ฉันพบปัญหาบางอย่างกับการใช้คำใบ้ประเภทการส่งคืนใน PHP 7 ความเข้าใจของฉันคือการบอกใบ้: self
หมายความว่าคุณตั้งใจให้คลาสการใช้งานกลับมาเอง ดังนั้นฉันจึงใช้: self
อินเทอร์เฟซเพื่อระบุสิ่งนั้น แต่เมื่อฉันพยายามใช้อินเทอร์เฟซจริงฉันพบข้อผิดพลาดเกี่ยวกับความเข้ากันได้
ต่อไปนี้เป็นการสาธิตง่ายๆเกี่ยวกับปัญหาที่ฉันพบ:
interface iFoo
{
public function bar (string $baz) : self;
}
class Foo implements iFoo
{
public function bar (string $baz) : self
{
echo $baz . PHP_EOL;
return $this;
}
}
(new Foo ()) -> bar ("Fred")
-> bar ("Wilma")
-> bar ("Barney")
-> bar ("Betty");
ผลลัพธ์ที่คาดหวังคือ:
เฟรดวิลมาบาร์นีย์เบ็ตตี้
สิ่งที่ฉันได้รับคือ:
PHP Fatal error: Declaration of Foo :: bar (int $ baz): Foo ต้องเข้ากันได้กับ iFoo :: bar (int $ baz): iFoo ใน test.php ในบรรทัดที่ 7
สิ่งนี้คือ Foo คือการใช้งาน iFoo ดังนั้นเท่าที่ฉันสามารถบอกได้ว่าการใช้งานควรเข้ากันได้ดีกับอินเทอร์เฟซที่กำหนด ฉันสามารถแก้ไขปัญหานี้ได้โดยการเปลี่ยนอินเทอร์เฟซหรือคลาสการใช้งาน (หรือทั้งสองอย่าง) เพื่อส่งคืนคำใบ้อินเทอร์เฟซตามชื่อแทนที่จะใช้self
แต่ความเข้าใจของฉันคือความหมายหมายself
ถึง "ส่งคืนอินสแตนซ์ของคลาสที่คุณเพิ่งเรียกเมธอดบน ". ดังนั้นการเปลี่ยนเป็นอินเทอร์เฟซจะหมายถึงในทางทฤษฎีว่าฉันสามารถส่งคืนอินสแตนซ์ของบางสิ่งที่ใช้อินเทอร์เฟซได้เมื่อเจตนาของฉันคืออินสแตนซ์ที่เรียกใช้คือสิ่งที่จะถูกส่งกลับ
นี่เป็นการกำกับดูแล PHP หรือเป็นการตัดสินใจออกแบบโดยเจตนา? หากเป็นแบบเดิมจะมีโอกาสเห็นการแก้ไขใน PHP 7.1 หรือไม่? ถ้าไม่เช่นนั้นวิธีการส่งคืนที่ถูกต้องคืออะไรที่บอกเป็นนัยว่าอินเทอร์เฟซของคุณคาดว่าคุณจะส่งคืนอินสแตนซ์ที่คุณเพิ่งเรียกว่าเมธอดในการผูกมัด