การเขียนคุณสมบัติผ่านเมจิกใน OOP ใน PHP

เมธอดเมจิก __set ถูกเรียกใช้ เมื่อพยายามเปลี่ยนค่าของคุณสมบัติที่ไม่มีอยู่ หรือคุณสมบัติที่ถูกซ่อนไว้ โดยรับพารามิเตอร์ เป็นชื่อคุณสมบัติและค่าที่พยายามกำหนดให้มัน

มาดูตัวอย่างการใช้งานจริงกัน สมมติว่าเรามีคลาส Test แบบนี้:

Test.php<?php
  class Test
  {
    private $prop1;
    private $prop2;
  }
?>

มาสร้างเมธอดเมจิก __set ในคลาสนี้กัน โดยใช้ฟังก์ชัน var_dump เพื่อแสดงชื่อคุณสมบัติ ที่ถูกเข้าถึง และค่า ที่พยายามกำหนดให้คุณสมบัตินั้น:

Test.php<?php
  class Test
  {
    private $prop1;
    private $prop2;
    
    public function __set($property, $value)
    {
      var_dump($property . ' ' .$value);
    }
  }
?>

มาทดสอบการทำงานของคลาสของเรา:

index.php<?php
  $test = new Test;
  $test->prop = 'value'; // var_dump ของเมธอด __set จะแสดง 'prop value'
?>

ตอนนี้เราจะกำหนดค่า ให้กับคุณสมบัติที่มีชื่อเก็บอยู่ในตัวแปร $property:

Test.php<?php
  class Test
  {
    private $prop1;
    private $prop2;
    
    public function __set($property, $value)
    {
      $this->$property = $value; // กำหนดค่า
    }
  }
?>

ตอนนี้เราสามารถเขียนค่าลงในคุณสมบัติ private จากนอกคลาสได้:

index.php<?php
  $test = new Test;
  
  $test->prop1 = 1; // เขียน 1
  $test->prop2 = 2; // เขียน 2
?>

เราเขียนได้ แต่ตรวจสอบไม่ได้ว่ามีการเขียนอะไรลงไปหรือไม่ เพราะคุณสมบัติเป็น private

สามารถสร้าง getter สำหรับคุณสมบัติเหล่านี้หรือ เพียงใช้เมธอดเมจิก __get มาลองใช้วิธีที่สอง:

Test.php<?php
  class Test
  {
    private $prop1;
    private $prop2;
    
    public function __set($property, $value)
    {
      $this->$property = $value;
    }
    
    // เมธอดเมจิก getter สำหรับคุณสมบัติ:
    public function __get($property)
    {
      return $this->$property;
    }
  }
?>

ตอนนี้เราสามารถทดสอบการทำงานของคลาสของเราได้แล้ว มาทดสอบกัน:

index.php<?php
  $test = new Test;
  
  $test->prop1 = 1; // เขียน 1
  $test->prop2 = 2; // เขียน 2
  
  echo $test->prop1; // จะแสดง 1
  echo $test->prop2; // จะแสดง 2
?>

อันที่จริงแล้ว แน่นอนว่าเราไม่ควรอนุญาต ให้ทุกคนเขียนค่าลงในคุณสมบัติ private ได้ มิฉะนั้นความหมายของการมีคุณสมบัติ private ก็จะหายไป (ง่ายกว่าคือทำให้เป็น public ไปเลย)

ดังนั้นจึงควรใช้เมธอดนี้เฉพาะ เมื่อมีความจำเป็นจริงๆ เท่านั้น ในบทเรียนต่อไปเราจะยังดูตัวอย่าง การประยุกต์ใช้ที่ดีอีก