7.4+:
ข่าวดีที่จะมีการนำมาใช้ในรุ่นใหม่ ตามที่ @Andrea ชี้ให้เห็น ฉันจะทิ้งวิธีแก้ปัญหานี้ไว้ที่นี่เผื่อมีคนต้องการใช้ก่อน 7.4
7.3 หรือน้อยกว่า
จากการแจ้งเตือนที่ฉันยังคงได้รับจากกระทู้นี้ ฉันเชื่อว่าผู้คนจำนวนมากมี/กำลังประสบปัญหาเดียวกันกับฉัน วิธีแก้ปัญหาของฉันสำหรับกรณีนี้คือการรวม setters + __set
magic method ไว้ภายในลักษณะเพื่อจำลองพฤติกรรมนี้ นี่คือ:
trait SettersTrait
{
/**
* @param $name
* @param $value
*/
public function __set($name, $value)
{
$setter = 'set'.$name;
if (method_exists($this, $setter)) {
$this->$setter($value);
} else {
$this->$name = $value;
}
}
}
และนี่คือการสาธิต:
class Bar {}
class NotBar {}
class Foo
{
use SettersTrait; //It could be implemented within this class but I used it as a trait for more flexibility
/**
*
* @var Bar
*/
private $bar;
/**
* @param Bar $bar
*/
protected function setBar(Bar $bar)
{
//(optional) Protected so it wont be called directly by external 'entities'
$this->bar = $bar;
}
}
$foo = new Foo();
$foo->bar = new NotBar(); //Error
//$foo->bar = new Bar(); //Success
คำอธิบาย
ก่อนอื่น กำหนดให้ bar
เป็นทรัพย์สินส่วนตัว ดังนั้น PHP จะส่ง __set
โดยอัตโนมัติ
__set
จะตรวจสอบว่ามีตัวตั้งค่าบางตัวประกาศในวัตถุปัจจุบัน (method_exists($this, $setter)
) มิฉะนั้นมันจะตั้งค่าของมันตามปกติเท่านั้น
ประกาศวิธีการ setter (setBar) ที่ได้รับอาร์กิวเมนต์ประเภทคำแนะนำ (setBar(Bar $bar)
)
ตราบใดที่ PHP ตรวจพบว่ามีบางสิ่งที่ไม่ใช่ Bar
instance ถูกส่งผ่านไปยัง setter มันจะทำให้เกิดข้อผิดพลาดร้ายแรงโดยอัตโนมัติ: Uncaught TypeError: อาร์กิวเมนต์ 1 ที่ส่งผ่านไปยัง Foo::setBar() จะต้องเป็นอินสแตนซ์ของ Bar อินสแตนซ์ของ NotBar ที่ได้รับ
person
CarlosCarucce
schedule
19.06.2018