การใช้ 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');

การใช้งาน __noSuchMethod__ ใน javascript

ก่อนหน้านี้เคยแนะนำการใช้งาน __call() method ใน php มาแล้ว วันนี้จะเอา function __noSuchMethod__ มาแนะนำหลักการทำงานเหมือนกับการใช้งาน __call() ใน php เลย คือถ้ามีการเรียก method ที่ยังไม่ได้มีการสร้างไว้ มันก็จะเข้ามาทำงานใน method นี้ อย่างเช่นในตัวอย่างในรูปข้างล่างเราทำการเรียก method foo ซึ่งไม่ได้มีอยู่จริง ทำให้เข้าไปทำงานใน method ที่ชื่อว่า __noSuchMethod__ แทน และใน method นี้จะรับ parameter 2 ตัว คือตัวแรกจะเป็นชื่อ function ที่เรียก เช่นในตัวอย่างเราเรียก method foo ตัวแปรตัวแรกเราจะได้ค่าเป็น foo และตัวที่สองเป็น arguments ที่ส่งเข้ามาจะถูกส่งเข้ามาเป็น array

หลังจากพูดถึงความน่าสนใจของการใช้งาน __noSuchMethod__ ไปเรียบร้อยแล้ว ก็จะบอกข่าวร้ายว่าปัจจุบันยังใช้งานได้แค่ Firefox เท่านั้น (มาทำให้อยากแล้วจากไป ^_^) ส่วน webkit ยังไม่ support แต่เห็นมีข่าวว่ามีการบรรจุเข้าไปในแผนพัฒนา หวังว่าคงจะเอามาใช้งานได้ในเร็วๆนี้ แล้วก็ยังไม่ได้ลองใน opera และ IE เลยยังไม่รู้ว่าเป็นยังไง ฝากเอาไปทดลองกันดูละกัน ได้ผลยังไงก็บอกกันด้วยนะครับ

สามารถเข้าไปทดลอง code ได้ที่นี่ (เปิดด้วย Firefox เท่านั้น)
http://jsfiddle.net/irobust/LBxBw/

การใช้ __autoload() ใน php

วันนี้เราจะมาพูดถึง magic method ที่ชื่อว่า __autoload() ซึ่งจะทำการ load ไฟล์ PHP ที่เราทำการเรียกใช้ให้โดยอัตโนมัติ โดยจะดูจากการ new และการ Extends

วิธีใช้ง่ายๆโดยการสร้าง function ขึ้นมาแล้วรับ parameter มา 1 ตัวคือชื่อ Class ในตัวอย่างเราจะทำการ load ไฟล์ที่อยู่ใน folder Entity อันนี้แล้วแต่ว่า Class ของเราเก็บอยู่ที่ไหน

แต่สิ่งที่สำคัญที่สุดคือชื่อ Class และชื่อไฟล์ต้องตรงกัน