การใช้ Magic Method มาช่วยสร้าง getter และ setter

ใน IDE สำหรับการเขียน PHP จะไม่มีตัวช่วยในการสร้าง method getter และ setter เหมือนกับ Java หรือ C# ทำให้ลำบากมากในการสร้าง getter หรือ setter ก่อนอื่นเรามาลองทำความเข้าใจ getter และ setter เบื้องต้นก่อน ตามตัวอย่าง

1
2
3
4
5
6
7
8
9
10
11
class Person{
private $name;

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

public setName($value){
$this->name = $value;
}
}

ตามหลักการเขียนโปรแกรมแบบ Object Oriented เราควรจะทำการ encapsulation หรือทำการห่อหุ้มไม่ให้เข้าถึงตัว porperties ของ object นั้นโดยตรง จากตัวอย่างเราจะไม่สามารถทำการดึงค่า หรือกำหนดค่าให้กับ property name ของ object person โดยตรงได้เนื่องจากว่า property name ถูก set ไว้เป็น private เพื่อให้เราสามารถลดผลการะทบจากการเปล่ียนแปลงที่เกิดขึ้น เช่นการเปลี่ยนชื่อตัวแปร หรือการกำหนดเงื่อนไขของ property เช่น porperty name wไม่สามารถใส่ตัวเลขได้ รับได้เฉพาะตัวอีกษรเท่านั้นเราอาจเขียน check เงื่อนไขไว้ด่อนที่จะทำการ set value ให้กับ property name ได้ เช่น

1
2
3
4
5
6
public function setName($value){
if(ereg('[0-9]', $value, $regs)){
trigger_error('Invalid format for name');
}
$this->name = $value;
}

อย่างที่บอก PHP เราไม่มีตัวช่วยสำหรับการสร้าง method getter และ setter แต่เรามี magic method ซึ่งจะทำให้เราไม่ต้องสร้างทั้ง method getter และ setter

1
2
3
4
5
6
7
8
9
10
class Person{
private $name;
function __get($propertyName){
return $this->$propertyName;
}

function __set($propertyName, $value){
$this->$propertyName = $value;
}
}

เมื่อมีการเรียก property ที่ไม่ได้เปิดเป็น public หรือไม่ได้ประกาศไว้ จะเข้าไปใน method __get ทันที โดยจะส่ง parameter เข้ามา 1 ตัว คือ name ซึ่งเป็นชื่อของ property ที่เราต้องการเข้าถึง เราก็ทำการอ้างถึง property โดยการใช้คำสั่ง

1
$this->$propertyName

เวลาเจอการเขียนตัวแปรแปลกๆแบบนี้ให้ทำการแทนค่าไล่จากด้านขวามาทีละตัว เช่นในตัวอย่างนี้เราจะพยายาม get ค่า property name ออกมา โดยเรียก

1
2
$person = new Person;
echo $person->name;

Read more การใช้ Magic Method มาช่วยสร้าง getter และ setter

การใช้งาน magic method __call() ใน PHP

PHP magic method call

ใน PHP มี Magic Method ให้เราใช้หลายตัวมากๆ จากที่ได้เคยแนะนำไปแล้วเป็น __autoload() ที่ทำงานทุกครั้งเมื่อมีการ new object ส่วนวันนี้เราจะมาแนะนำ method __call (Magic Method ทุกตัวจะนำหน้าด้วย underscore 2 ตัวเสมอ)  ซึ่ง method call นี้จะทำงานก็ต่อเมื่อมีความพยายามเรียก method ของ class นั้นแต่ method นั้นไม่มีอยู่ มีฝาแฝดที่ทำงานคู่กันคือ __callStatic() เหมือนกับ call ทุกอย่างแต่จะเป็นการพยายามเรียก static method ซึ่งในตัวอย่างนี้เราเอา __call() มาเป็นตัวอย่าง จาก code ในรูป จะเป็นการสร้าง class Entity และใน class นี้มี method เดียวคือ myFunc() ซึ่งในที่นี้เราไม่ได้ทำอะไรกับ myFunc() นี้เลย มีไว้ให้ดูเฉยๆ code ในส่วนของ class ปกติก็มีแค่นี้

1
2
3
class Entity{
    function myFunc(){}
}

จากนั้นเราก็เพิ่ม Magic Method __call() เข้าไปโดยที่ในตัวอย่างนี้ตัว __call() แค่ทำการ echo ชื่อ method ที่พยายามเรียกและ arguments ที่ส่งเข้ามาเท่านั้นเอง ซึ่งตัว arguments นั้นจะส่งเข้ามาเป็น array ในการนำไปประยุกต์ใช้งานอาจเอาไปใช้กับการทำงานเป็น getter และ setter ของ property ใน class ได้ เราจะได้ไม่ต้องเขียน getter และ setter ใหม่ทุกครั้งเมื่อมีการเพิ่ม property ใหม่เข้ามา

1
2
3
4
5
6
7
class Entity{
    function myFunc(){}
    
    function __call($functionName, $args){
        echo 'Method'.$functionName.' with '.count($args).' arguments';
    }
}

ส่วนที่เหลือก็เป็นการเรียกใช้งานปกติซึ่ง ในตัวอย่างเราเรียกใช้ method miss() ซึ่งไม่ได้สร้างไว้ใน class นี้ แต่ถ้าเราเรียก method ก็จะเข้าไปทำงานใน myFunc() ปกติ ไม่เกี่ยวข้องกับ __call() แต่อย่างใด

1
2
$entity = new Entity();
$entity->miss('param');