Skip to main content

เนื้อหาภาษาไทย / Thai content

System guide Content reviewed

__get และ __set Methods: การจัดการ Properties ที่ไม่มีอยู่

__get และ __set Methods: การจัดการ Properties ที่ไม่มีอยู่

ในบทที่แล้ว เราได้รู้จักกับ Magic Methods ต่างๆ ใน PHP กันไปแล้ว คราวนี้ เราจะมาเจาะลึกกันที่ __get และ __set ซึ่งเป็น Magic Methods ที่มีความสำคัญในการจัดการ Properties ที่ไม่มีอยู่จริงใน Class ของเรา

__get คืออะไร?

__get เป็น Magic Method ที่ถูกเรียกใช้งานโดยอัตโนมัติ เมื่อเราพยายามเข้าถึง Property ที่ไม่มีอยู่ (undefined) หรือ Property ที่ถูกประกาศเป็น private หรือ protected จากภายนอก Class

รูปแบบการใช้งาน:

public function __get($name) {
    // Logic ในการจัดการ Property ที่ไม่มีอยู่
}
  • $name คือชื่อของ Property ที่เราพยายามเข้าถึง

ตัวอย่างการใช้งาน __get

สมมติว่าเรามี Class ชื่อ Product ซึ่งมี Property price ที่ถูกประกาศเป็น private และเราต้องการให้สามารถเข้าถึง price จากภายนอกได้ แต่ต้องการเพิ่ม Logic บางอย่างก่อนที่จะส่งค่ากลับไป

class Product {
    private $price;

    public function __construct($price) {
        $this->price = $price;
    }

    public function __get($name) {
        if ($name === 'price') {
            // เพิ่ม Logic เช่น การปัดเศษ หรือการแปลงหน่วย
            return round($this->price, 2);
        } else {
            return "Property '$name' does not exist.";
        }
    }
}

$product = new Product(19.995);
echo $product->price; // Output: 20
echo $product->nonExistentProperty; // Output: Property 'nonExistentProperty' does not exist.

คำอธิบาย:

  • เมื่อเราพยายามเข้าถึง $product->price, PHP จะตรวจสอบว่า price เป็น Property ที่เข้าถึงได้หรือไม่ เนื่องจาก price เป็น private, PHP จะเรียกใช้งาน __get('price') โดยอัตโนมัติ
  • ภายใน __get, เราตรวจสอบว่า $name คือ 'price' หรือไม่ ถ้าใช่ เราจะปัดเศษ $this->price เป็นทศนิยม 2 ตำแหน่ง แล้วส่งค่ากลับไป
  • ถ้าเราพยายามเข้าถึง Property อื่นๆ ที่ไม่มีอยู่ (เช่น $product->nonExistentProperty), __get จะส่งข้อความแสดงข้อผิดพลาดกลับไป

__set คืออะไร?

__set เป็น Magic Method ที่ถูกเรียกใช้งานโดยอัตโนมัติ เมื่อเราพยายามกำหนดค่า (assign) ให้กับ Property ที่ไม่มีอยู่ (undefined) หรือ Property ที่ถูกประกาศเป็น private หรือ protected จากภายนอก Class

รูปแบบการใช้งาน:

public function __set($name, $value) {
    // Logic ในการจัดการ Property ที่ไม่มีอยู่
}
  • $name คือชื่อของ Property ที่เราพยายามกำหนดค่า
  • $value คือค่าที่เราต้องการกำหนดให้กับ Property

ตัวอย่างการใช้งาน __set

สมมติว่าเรามี Class ชื่อ User ซึ่งมี Property name ที่ถูกประกาศเป็น private และเราต้องการให้สามารถกำหนดค่า name จากภายนอกได้ แต่ต้องการตรวจสอบความถูกต้องของข้อมูลก่อนที่จะกำหนดค่า

class User {
    private $name;

    public function __set($name, $value) {
        if ($name === 'name') {
            if (is_string($value) && strlen($value) > 3) {
                $this->name = $value;
            } else {
                echo "Invalid name. Name must be a string and at least 4 characters long.";
            }
        } else {
            echo "Property '$name' cannot be set.";
        }
    }

    public function getName() {
        return $this->name;
    }
}

$user = new User();
$user->name = "John Doe";
echo $user->getName(); // Output: John Doe

$user->name = "Jo"; // Output: Invalid name. Name must be a string and at least 4 characters long.
echo $user->getName(); // Output: John Doe (ค่าเดิมยังคงอยู่)

$user->age = 30; // Output: Property 'age' cannot be set.

คำอธิบาย:

  • เมื่อเราพยายามกำหนดค่า $user->name = "John Doe", PHP จะตรวจสอบว่า name เป็น Property ที่กำหนดค่าได้หรือไม่ เนื่องจาก name เป็น private, PHP จะเรียกใช้งาน __set('name', "John Doe") โดยอัตโนมัติ
  • ภายใน __set, เราตรวจสอบว่า $name คือ 'name' หรือไม่ ถ้าใช่ เราจะตรวจสอบว่า $value เป็น String และมีความยาวมากกว่า 3 ตัวอักษรหรือไม่ ถ้าใช่ เราจะกำหนดค่า $this->name เป็น $value
  • ถ้าเราพยายามกำหนดค่าที่ไม่ถูกต้อง (เช่น $user->name = "Jo"), __set จะแสดงข้อความแสดงข้อผิดพลาด และจะไม่ทำการเปลี่ยนแปลงค่า $this->name
  • ถ้าเราพยายามกำหนดค่าให้กับ Property อื่นๆ ที่ไม่มีอยู่ (เช่น $user->age = 30), __set จะแสดงข้อความแสดงข้อผิดพลาด

ข้อดีของการใช้ __get และ __set

  • การควบคุมการเข้าถึง Properties: เราสามารถควบคุมการเข้าถึงและแก้ไข Properties ของ Object ได้อย่างละเอียด
  • การเพิ่ม Logic ก่อนการเข้าถึง/แก้ไข: เราสามารถเพิ่ม Logic เช่น การตรวจสอบความถูกต้องของข้อมูล, การแปลงหน่วย, หรือการคำนวณค่า ก่อนที่จะส่งค่ากลับไป หรือก่อนที่จะกำหนดค่าให้กับ Property
  • การสร้าง Properties แบบ Dynamic: เราสามารถสร้าง Properties แบบ Dynamic (Properties ที่ไม่ได้ถูกกำหนดไว้ใน Class) ได้
  • Code ที่สะอาดและอ่านง่าย: ช่วยให้ Code ของเรามีความเป็นระเบียบและอ่านง่ายยิ่งขึ้น

ข้อควรระวังในการใช้ __get และ __set

  • ประสิทธิภาพ: การใช้ __get และ __set อาจทำให้ Code ของเราทำงานช้าลงเล็กน้อย เนื่องจาก PHP ต้องเรียกใช้งาน Magic Methods เหล่านี้
  • ความซับซ้อน: การใช้งาน __get และ __set ที่มากเกินไป อาจทำให้ Code ของเราซับซ้อนและยากต่อการบำรุงรักษา
  • การ Debug: การ Debug Code ที่ใช้ __get และ __set อาจทำได้ยากกว่า Code ที่ไม่ได้ใช้ Magic Methods เหล่านี้

กรณีใช้งานจริง

ORM (Object-Relational Mapping): Frameworks ORM หลายตัวใช้ __get และ __set เพื่อจัดการกับ Columns ใน Database โดยไม่ต้องกำหนด Properties เหล่านั้นใน Class

Model Attributes: ใน Frameworks MVC หลายตัว, __get และ __set ถูกใช้เพื่อจัดการกับ Attributes ของ Model โดยมีการตรวจสอบความถูกต้องของข้อมูลและแปลงข้อมูลก่อนที่จะทำการบันทึกลง Database

ข้อผิดพลาดที่พบบ่อย

  • ลืมตรวจสอบชื่อ Property: การไม่ตรวจสอบชื่อ Property ($name) ใน __get และ __set อาจทำให้เกิดพฤติกรรมที่ไม่คาดฝัน
  • การเข้าถึง Properties แบบ Recursive: การเรียกใช้งาน __get หรือ __set ภายใน __get หรือ __set เอง อาจทำให้เกิด Infinite Loop
  • การไม่จัดการกับ Exceptions: หากเกิด Exception ภายใน __get หรือ __set, ควรจัดการกับ Exception เหล่านั้นอย่างเหมาะสม เพื่อป้องกันไม่ให้ Application ของเราหยุดทำงาน

สรุปแล้ว __get และ __set เป็น Magic Methods ที่มีประโยชน์ในการจัดการ Properties ที่ไม่มีอยู่จริงใน Class ของเรา อย่างไรก็ตาม เราควรใช้งาน Magic Methods เหล่านี้อย่างระมัดระวัง เพื่อป้องกันไม่ให้ Code ของเราซับซ้อนและยากต่อการบำรุงรักษา ในบทถัดไป เราจะมาเรียนรู้เกี่ยวกับ Magic Methods __call และ __callStatic ซึ่งเป็น Magic Methods ที่ใช้ในการจัดการ Methods ที่ไม่มีอยู่จริง

Office.in.th Custom Service

Want to build or adapt a system from this structure?

Office.in.th designs and develops enterprise web applications, API integrations, and public- and private-sector management systems, with long-term support.

See our software development service