PlusMagi's Blog By Pitt Phunsanit

PHP: Constructor Property Promotion

PHP: Constructor Property Promotion เป็นฟีเจอร์ที่ถูกเพิ่มเข้ามาตั้งแต่ PHP 8.0 ซึ่งช่วยให้เราสามารถประกาศและกำหนดค่าให้กับ Property (ตัวแปรของคลาส) ได้โดยตรงภายใน Constructor เลย พูดง่าย ๆ คือมันช่วยลดโค้ดที่ซ้ำซ้อน (Boilerplate code) ลงไปได้เยอะมากครับ

เพื่อให้เห็นภาพชัดเจน ลองมาดูการเปรียบเทียบระหว่างแบบเดิม กับแบบใหม่กันครับ


เปรียบเทียบแบบเก่า vs แบบใหม่

สมมติว่าเราต้องการสร้างคลาส User ที่มี property 3 ตัวคือ id, name และ email

แบบเดิม (ก่อน PHP 8.0): เราต้องประกาศ Property ด้านบน ทำ Type hinting จากนั้นก็ต้องมาเขียนสั่ง $this->... = $... ซ้ำๆ อีกรอบใน constructor

class User {
    public int $id;
    public string $name;
    public string $email;

    public function __construct(int $id, string $name, string $email) {
        $this->id = $id;
        $this->name = $name;
        $this->email = $email;
    }
}

แบบใหม่ที่ใช้ Constructor Property Promotion:

เราสามารถใส่ Visibility Keyword (public, protected, private) ไว้ข้างหน้าพารามิเตอร์ใน constructor ได้เลย PHP จะเข้าใจทันทีว่าเราต้องการให้มันเป็นทั้ง Property ของคลาส และรับค่าไปพร้อมกัน

class User {
    public function __construct(
        public int $id,
        public string $name,
        public string $email
    ) {} // ตัว Body ของ constructor ปล่อยว่างไว้ได้เลยถ้าไม่มีลอจิกอื่น
}

ผลลัพธ์: โค้ดสั้นลง อ่านง่ายขึ้น และลดโอกาสเขียนชื่อตัวแปรผิดไปได้เยอะเลยครับ


กฎและข้อควรรู้ในการใช้งาน

แม้ว่าจะสะดวกมาก แต่ก็มีข้อกำหนดบางอย่างที่ต้องระวังครับ


แล้วถ้ายังอยากมี Logic ใน Constructor ล่ะ?

ถ้าเราจำเป็นต้องเช็คความถูกต้องของข้อมูล (Validation) ก่อนบันทึกค่า ก็ยังสามารถเขียนโค้ดลงไปใน {} ของ constructor ได้ตามปกติครับ เพราะ PHP จะแอบแปลงโค้ดและส่งค่าเข้า property ให้เราก่อนที่โค้ดใน {} จะทำงาน

class Product {
    public function __construct(
        public string $name,
        public float $price
    ) {
        // สามารถเขียน logic ตรวจสอบต่อได้ทันที
        if ($this->price < 0) {
            throw new InvalidArgumentException("ราคาติดลบไม่ได้นะ!");
        }
    }
}

อ่านเพิ่มเติม

Exit mobile version