Google


Tag Archive for 'OOP'

Slide "GoOO->PHP [5] at Barcamp Bangkok 2"

Slide : PHP 5 OOP By Ilia Alshanetsky

ไม่มีอะไรมากสำหรับ entry นี้ พอดีว่าเจอจาก Scribd เลยขอเอามาเปะแล้วกันครับ ;)

เป็น Slide จากงาน International PHP Conference 2005 ครับผม

โดยจากที่นั่งอ่าน นี่อธิบายได้ดีมากเลยหล่ะ โดยมีส่วนเปรียบเทียบกับของเก่าอย่าง PHP 4 แล้วยังบอกอีกด้วยว่า การใช้รูปแบบเก่า ๆ จะเกิดอะไรขึ้นบ้าง ถือว่าละเอียดมาก ๆ Slide นึงเลยครับ มีไฟล์เสียงด้่วยนะครับ ลองเข้าไปฟังต่อใน Scribd เอาแล้วกันครับ ;P

Read this document on Scribd: PHP 5 OO

การใช้ Object ใน PHP 4 กับ 5 ต่างกันยังไง ? (ภาค 1)

การ Initialize Object เพื่อให้ได้ Object ใน PHP 4 นั้นจะเป็นการ Pass-by-Value แต่ใน PHP 5 จะเป็นการ Pass-by-Reference แทน จากโค้ดตัวอย่างด้านล่างนี้

PHP:
  1. class userClass {
  2.     var $data = 'Hello';
  3.     function talk() {
  4.         echo $this->getData();
  5.     }
  6.     function setData($val){
  7.         $this->data = $val;
  8.     }
  9.     function getData(){
  10.         return $this->data;
  11.     }
  12. }

ทำการ Initialize Object โดยกำหนดชื่อ Reference-Name ว่า $obj1

PHP:
  1. // PHP 5
  2. // Assigned-by-Value Format
  3. // Override operation with Assigned-by-Reference
  4. $obj1 = new userClass();
  5.  
  6. // PHP 4
  7. // Assigned-by-Value Format
  8. // Used more memory
  9. $obj1 = new userClass();
  10.  
  11. // PHP 4 same way with PHP 5
  12. // Assigned-by-Reference Format
  13. // E_STRIC Error in PHP 5 and Removed in PHP 6
  14. $obj1 =& new userClass();

CODE:
  1. $obj1 --------> [OBJECT DATA]

ในการ Initialize Object ใน PHP 4 นั้น ถ้าใช้แบบทั่วไปใช้ใช้กันคือแบบ Assigned-by-Value นั้น Object ที่ถูกสร้างขึ้นมาตอน Initialize แล้วถูก copy (clone) ไปยังตัวแปรที่เราสร้างขึ้นมา ซึ่งการทำแบบนี้จะเสีย memory เพิ่มขึ้น แต่ถ้าใช้การ Initialize Object แบบ Reference กับตัวแปร object แทนการ copy (clone) ข้อมูลใส่ตัวแปรนั้น โดยต้องใช้การทำ Assigned-by-Reference แทนแบบ Assigned-by-Value โดยที่ Initialize Object เพื่อสร้าง Object จะมีการสร้างบนหน่วยความจำ แล้วมีตัวแปรไป Reference มันเพื่ออ้างอิงค่าแทน

แต่ใน PHP 5 นั้นการ Initialize Object ก็ใช้รูปแบบ Assigned-by-Value ไปเลย แบบเดียวกับ Java ซะ แต่ผลก็จะเป็นการอ้างอิงแบบ Assigned-by-Reference ไปเลยในตัว ซึ่งการทำแบบนี้นั้นรวมไปถึงการทำ Assign-Value, Return-Value และการ Pass-Parameter ด้วย

เมื่อเรานำไปใช้ตามตัวอย่างด้านล่างนี้

PHP:
  1. $obj1->talk();
  2.  
  3. $obj2 = $obj1;
  4.  
  5. $obj1->talk();
  6.  
  7. $obj2->setData("Hi");
  8.  
  9. $obj1->talk();

ก็จะได้ผลของ PHP 5 คือ

CODE:
  1. Hello
  2. Hi

โดยการทำงานนั้น $obj1 นั้นจะเรียก Method talk มา แล้วทำการ Assigned-by-Reference ให้กับ $obj2 ทำให้ต่อไปเมื่อใช้งาน $obj2 ก็จะเหมือนกับใช้ $obj1 นั้นเอง (ทั้งการแก้ไข และเรียกใช้) เพราะตัวแปรทั้งสองตัว มันอ้างอิง Memory Address เดียวกัน

CODE:
  1. $obj1 --------> [OBJECT DATA]
  2.           |
  3. $obj2 ----|

ส่วน PHP 4 คือ

CODE:
  1. Hello
  2. Hello

โดยการทำงานนั้น $obj1 นั้นจะเรียก method talk มา แล้วทำการ Assigned-by-Value หรือเรียกว่า clone ให้กับ $obj2 ทำให้ $obj2 นั้นมีค่าเหมือนกับ $obj1 เพียงแต่ถ้ามีการแก้ไขค่าที่ $obj2 จะไม่มีผลกระทบกับ $obj1 เลย

CODE:
  1. $obj1 --------> [OBJECT DATA]
  2.          
  3. $obj2 --------> [OBJECT DATA]

แต่ถ้าเราต้องการ copy (clone) ค่า ใน PHP 5 ได้มี keyword เพิ่มขึ้นมาชื่อ clone ครับ

โดยเปลี่ยนการ Assigned-by-Value เพียงเล็กน้อยโดยเพิ่ม keyword ไปด้านหลังเครื่องหมาย Assigned (=) ได้ตามนี้

PHP:
  1. $obj2 = clone $obj1;

เมื่อทำแบบนี้ด้านบนก็จะเป็นการ copy (clone) ค่าให้กับอีกตัวแปรนึงให้มันไป Reference กับ Objet ที่ถูก clone ไปอีกก้อนนึงแบบเดียวกับ Assigned-by-Value แบบ PHP 4 นั้นเอง

CODE:
  1. $obj1 --------> [OBJECT DATA]
  2.          
  3. $obj2 --------> [OBJECT DATA]

จากการทำงานด้านบนจะเห็นว่าใน PHP 5 นั้นการ Pass-Parameter, Initialize Object, Assign-Value และ Return-Value นั้นจะส่งแค่ค่าของ Reference-Address ออกไปเท่านั้น ซึ่งเป็นผลทำให้ใช้ Method Chaining ไปได้เลยในตัว

ต่อมาผมทำการเพิ่ม Method เข้าไปอีก 1 ตัวเพื่อทำสอบการทำ Method Chaining

PHP:
  1. class userClass {
  2.     var $data = 'Hello';
  3.     function talk() {
  4.         echo $this->getData();
  5.     }
  6.     function setData($val){
  7.         $this->data = $val;
  8.     }
  9.     function getData(){
  10.         return $this->data;
  11.     }
  12.     function chaining() {
  13.         return $this;
  14.     }
  15. }

โดยการ Return ที่ตัว keyword $this นี้ออกไป การ Return-Value นี้เป็นการ Return ที่เอา Reference Address ออกมาไปส่วนต่อให้อ้างอิงกับ Address ของ Object นั้น ๆ ทำให้ใช้งาน Method ของ Object นี้ต่อไปได้เรื่อย ๆ ครับ ดังตัวอย่างด้านล่างครับ

PHP:
  1. $obj1->chaining()->talk();

ก็จะได้ผลดังนี้ครับ

CODE:
  1. Hello
  2. Hi
  3. Hi

ต่อมาเรามาทดสอบเรื่องการ Pass-Parameter โดยทดสอบว่ามันจะ Pass-by-Reference ถึงแม้ว่าจะ กำหนด Parameter ที่ Pass-by-Value ไว้ก็ตามที โดยในโค้ดด้านล่างนี้ ได้เพิ่ม Method prototypeMod เข้าไป โดยส่ง Object และ Value ลงไปเพื่อ Assign ค่าให้กับ Object ตัวที่ Pass-Parameter ลงไป

PHP:
  1. class userClass {
  2.     var $data = 'Hello';
  3.     function talk() {
  4.         echo $this->getData();
  5.     }
  6.     function setData($val){
  7.         $this->data = $val;
  8.     }
  9.     function getData(){
  10.         return $this->data;
  11.     }
  12.     function chaining() {
  13.         return $this;
  14.     }
  15.     function prototypeMod($obj, $val) {
  16.         $obj->setData($val);
  17.         return $obj;
  18.     }
  19. }

แล้วเมื่อผมนำไปใช้ก็ทำการส่ง $obj2 ลงไปแล้วตั้งค่า Hello ลงไป แล้วทำ Chaining เรียก talk ของ $obj2 ออกมาใช้งาน แล้วก็เรียก talk ของ $obj1 ด้วยเช่นกั

PHP:
  1. $obj1->prototypeMod($obj2, 'Hello')->talk();
  2.  
  3. $obj1->talk();

ผลที่ได้คือ

CODE:
  1. Hello
  2. Hello

จะเห็นว่าถ้าเราส่ง Object ด้วยการ Pass-Parameter เข้าไปใน function หรือ method จะเป็นการ Pass-by-Reference ครับ ซึ่งต้องระวังอย่างมาถ้า upgrade จาก PHP 4 มา 5 ครับ ที่บางครั้งค่าที่ได้อาจจะแตกต่างในช่วงการทำงานครับ ต้องระวังเรื่องของ logic-error ให้ดีครับ ซึ่งถ้าคนที่ไม่เคยเขียน Programming Language พวก Java, C# หรือ VB.NET มาก่อนอาจจะงง เพราะ PHP 4 นั้น Object จะถูกเรียกว่า "objects are not any longer just 'improved arrays'." ซึ่งใน PHP 5 นั้นได้ลบแนวคิดนี้ออกไป ให้เป็นแบบเดียวกับภาษา Object Oriented Programming อื่น ๆ ครับ

ดังนั้นต่อไปถ้าใช้ใน PHP 5 ไม่ต้องทำการ Initialize Object แบบ Assigned-by-Reference อีกต่อไปครับ และการทำ Assigned-by-Reference ในการ Initialize Object จะใช้งานไม่ได้แล้วใน PHP 6 ด้วย โดยใน PHP 5 จะขึ้น E_STRIC Error Message ด้วยเช่นกันครับ

ปล. entry นี้เล่นซะเหนื่อยเพราะว่านั่งแก้ format ของ code ซะเมามันกับนั่งไล่ keyword ต่าง ๆ ให้มันตรงกับที่เค้าใช้กัน เพราะส่วนตัวเองก็ไม่แม่นพวก technical term บางตัวว่าใช้คำว่าอะไรเท่าไหร่ เพราะคืนอาจารย์ไปบ้างแล้ว -_-' (แต่รู้ว่ามันคืออะไรนะ เพียงแต่ใช้คำไม่ถูก) ถ้าส่วนไหนไม่เข้าใจก็โพสความคิดเห็นถามเพิ่มเติมกันมาได้นะครับ

เพิ่มเติม (2/6/2551 18:00)

In PHP 5 there is a new Object Model. PHP's handling of objects has been completely rewritten, allowing for better performance and more features. In previous versions of PHP, objects were handled like primitive types (for instance integers and strings). The drawback of this method was that semantically the whole object was copied when a variable was assigned, or pass as a parameter to a method. In the new approach, objects are referenced by handle, and not by value (one can think of a handle as an object's identifier).

และใน Zend Engine 2 ที่เป็นแกนหลักของ PHP 5 ได้ให้คำจำกัดความไว้ว่า "In the new approach, objects are referenced by handle, and not by value"

อ้างอิงจาก

OOP in PHP Series [Thai language]

ผมเอา OOP in PHP ทั้ง 4 ตอนที่ลงใน ThaiAdmin Magazine ไปลงใน scribd ใน folder "OOP in PHP Series [Thai language]" แล้ว ซึ่ง ๆ ผมยังเขียนไม่จบ Series ดี ThaiAdmin Magazine ก็หยุดลงที่เล่ม 4 ไปครับ แต่ว่าผมยังไม่หยุดเขียนครับ โดยผมจะหาเวลาว่าง ๆ เขียนต่อที่ 5 และตอนต่อ ๆ ไปเรื่อย ๆ จนกว่าจะหมดภูมิความรู้ ไปข้างนึง -_-'

เข้าไปได้ที่ OOP in PHP Series [Thai language] ครับ สามารถโหลดเป็น PDF format ไปอ่านต่อได้ครับ

สัญญาอนุญาติแบบ Attribution-Noncommercial-No Derivative Works 3.0 Unported ครับผม

บทความ OOP in PHP ตอนที่ 1 สำหรับลงใน ThaiAdmin Magazine เสร็จแล้ว เย้ …….

กว่าจะเขียนเสร็จเล่นเกือบตาย ไม่ใช่ว่ามันยากหรืออะไรหรอกครับ แต่ว่าการอธิบายให้ดูง่าย ๆ นี่มันทำยากกว่ามาก ๆ แถมการใช้ศัพท์ใด ๆ ต้องคิดถึงคนที่ไม่รู้ด้วยเป็นทุน ไม่งั้นมันจะส่งสารให้กับคนอ่านยากลำบากมาก โดยในบทความพยายามที่จะไม่ยัดศัพท์ทางเทคนิคใน OOP ลงไปแต่จะอาศัยการคำพูดไทย ๆ ที่เปรียบเทียบให้เห็นแล้ววงเล็บศัพท์เทคนิคตรงนั้นไป แล้วพยายามเอาเรื่องใกล้ ๆ ตัวมาอธิบายให้รูปแบบ OOP แทน ค่อย ๆ สอนเป็นขั้นเป็นตอน อะไรที่มันดูยาก ๆ อธิบายยาว ๆ ก็ตัดออกไปก่อนอย่าง Polymorphism นีไม่อธิบายเลย เอาหลัก ๆ 3 ส่วนพวก Abstract Data type, Encapsulation และ Inheritance ให้เห็นภาพก่อน แล้วค่อยเอาเรื่องยาก ๆ โดยมีการใช้ภาพประกอบอยู่หลายส่วน และนำเอาเรื่อง Object Model และ Reference Variable กับความสัมพันธ์ของ Object มาพูดด้วยโดยอาศัยหลักการ Object แท้ ๆ ในระดับล่างว่ามันทำงานอย่างไร เพื่อให้เห็นภาพว่าการที่เรา initialized แล้วมันเกิดอะไรขึ้นบ้าง แล้วไอ้ตัวแปรที่เป็น Object ตัวนั้นน่ะ จริง ๆ แล้วมันก็แค่ชื่อตัวแปร แต่ตัว Object จริง ๆ มันอยู่ในหน่วยความจำอีกทีหนึ่ง อะไรแบบนี้ เพราะไม่งั้นจะสับสนว่ามันก็แค่ตัวแปรตัวหนึ่ง แต่จริง ๆ แล้วมันมีอะไรมากกว่านั้น อ่อ ลืมไปว่าในนั้นก็ใส่เรื่องการส่ง Message ระหว่าง Object ลงไปในนั้นด้วย คงประมาณนี้ มีเขียน Hello World และให้ดูความแตกต่างว่าได้ Object มา 2 ตัวมันทำงานแตกต่างกันได้อย่างไร อะไรประมาณนี้ คงต้องอ่านในนิตยสารเอาหล่ะครับ ;) เพิ่งส่งให้ตอนเย็นนี้เอง แล้วเจอกันในนิตยสาร ThaiAdmin เล่ม 1 วันที่ 8 กุมพาพันธ์ 2550 นี้นะครับ ที่งาน Com world ครับ

บ่นนิดๆ สะกิดหน่อยๆ (Core Programming)

เมื่อ blog อันเมื่อกี้ไม่ได้ทักทายมาอันนี้ทักทายนิดดีกว่า

คือที่หายไปเพราะว่ามี project SAD แล้วเดี่ยวต้องทำ project Database ต่ออีก โอ้ววววววว ยังไม่พอนะท่านๆ ตอนนี้ทำ Project ขนาดใหญ่พอสมควร ทำคนเดียว อีก เวรกรรม เพราะว่าเพื่อนๆ ใน section และชั้นปีมันคงไม่มีใครเขียน PHP และทำงานบน MySQL ได้ (แค่ SQL ทำงานแบบ SELECT กว่า 80% ยังคงใช้งานไม่เก่งเพียงพอ ขื่นมาช่วยทำเกรงว่าเวลา train กับเวลาทำเอง จะพอๆ กันกลายเป็นงาน x2 ไป -_-”) แถมเขียน PHP แบบ OOP อีก ยิ่งไปใหญ่ เพราะอย่างที่บอกไป Concept OOP ถ้าคนไม่เข้าใจจะโคตร งง ผมก็ไม่ได้เก่งเท่าไหร่ แต่เอามาใช้งานได้ก็ถือว่า OK แหละ

คือเขียน PHP แบบ OOP นี่มันค้อนข้างจะผิดหลักพอสมควร (Version 4 ครับ) มันไม่ Encapsule เลย เซง แต่ก็พยายาม lock ตัวเอง และอื่นๆ ไม่ให้มันออกมานอก Class ได้แบบไม่ตั้งใจ ทุกๆ อย่างทำงานผ่าน Method หมด กันไว้ก่อน เพราะว่ามันปรับแต่งผ่าน Method ให้มันจัดการกับตัวแปรต่างๆ ได้ง่ายกว่าด้วย ขื่นให้ดึงไปใช้ได้ดื้อๆ มันจะมีปัญหาแน่นอน …. ตอนปรับแต่ง code บางคนที่มามอง class อาจดูโง่ๆ แต่ถือว่าเผื่ออนาคตดีกว่า มันไม่แน่ไม่นอน เพราะว่ายิ่งใกล้ทำ prototype ให้เค้ายิ่งมี request ที่ไม่ตรงกับ interfact และ operation ของเรามากขึ้น ยิ่งต้องเตรียมการไว้ก่อน จะได้สบายหน่อย

แต่ PHP แบบ OOP ถือว่าเขียนง่ายนะ สำหรับ Version 4 แต่ถ้า Version 5 ผมว่า OK กว่า แต่ว่าหา Server มา Run มันยากเลยต้องยึด เจ้า Version 4 ไปก่อนดีกว่า เพราะว่า Version 5 มันไปไกล และเขียนได้ดูเป็น OOP มาก และจัดการตัวแปร ง่ายกว่าเยอะ ทำให้ผมโปรแกรมภายในได้ง่ายกว่าเยอะเลย แต่ก็เล็กกับข้อกำหนดจุกจิกสักหน่อย แต่ไม่หวั่น เพราะว่าC++ มันมีเยอะกว่า เลยเฉยๆ ฮา …….

แต่เมื่อวานนี้คุยกับรุ่นน้องคนนึงมาคุยเรื่องเขียนโปรแกรมแบบ OOP ไม่รู้เรียนอีท่าไหน เอาตัวแปรมาใส่ Public เพียบเลย แถมถามกลับไปว่ารู้จักใช้ get/set ป่าว ตอบกลับมาแบบ งง ว่า “คือไร” ไอ้เราก็เซงเลยดิ อืมมมมม นะ

คือไม่ใช่อะไรหรอก การจัดการตัวแปร ต้องผ่าน method ที่ขึ้นต้นด้วย get (เข้าถึง) และ set (ตั้งค่า) ด้วยเหตุผลว่า การเข้าถึงแบบ method นั้น เราสามารถโปรแกรมได้ว่าจะ get/set แล้วมีขั้นตอนอย่างไรบ้าง โดยที่ข้อมูลที่ “ตั้งค่า” และ “เข้าถึง” นั้นจะถูกนำไปใช้งาน หรือได้รับออกมาได้ถูกต้องตรงตามที่มันควรจะเป็นไป เช่น(ตัวอย่าง PHP นะ)
$x->set_month(15); // มันจะไม่ได้ เพราะว่าใน method นี้จะมีการตรวจเช็คว่า value >0 and <13 อยู่ และ return หรือ echo ออกมาว่า เกินกว่าจำนวนเดือนที่เป็นจริง แต่ถ้าเป็น
$y->date_month = 15; // มันจะใส่ได้ และไม่ขึ้น error หรือ echo อะไร เพราะว่ามันเป็นการใส่ค่าไปตรงๆ โดยไม่มีการตรวจสอบแบบด้านบน

ส่วน get ก็ประมาณเดียวกัน แต่ว่าการ get อาจจะเอามาใช้ในการแปลงตัวแปรต่างๆ ได้เช่นกัน ประมาณว่า
echo($x->get_month_name(12)); // มันก็จะเอา 12 ไปเทียบกับ string แล้ว return ค่าเป็นชื่อเดือนแทน อะไรประมาณนี้

เห็นแมะ ถ้าจัดการผ่าน method มันจะทำให้เราเขียนจัดการตัวแปรเข้า และออกจาก object ได้ง่าย และถูกต้องตรงตามความจริงได้ง่ายๆ เลย

ใครคิดว่า OOP มันเป็นอะไรที่ยาก ลองศึกษาและคิดใหม่น่าจะดีนะ ;)






Close
E-mail It