ผู้เขียน หัวข้อ: PHP เขียนแบบ OOP เบื้องต้น  (อ่าน 20318 ครั้ง)

ออฟไลน์ ผู้ดูแลระบบ

  • Administrator
  • Jr. Member
  • *****
  • กระทู้: 64
  • +0/-0
    • ดูรายละเอียด
PHP เขียนแบบ OOP เบื้องต้น
« เมื่อ: ตุลาคม 05, 2017, 08:21:07 pm »
Class เบื้องต้นและการกำหนด visibility
visibiliry คือการกำหนดคุณสมบัติในการเข้าถึง

ตัวอย่างนี้เรามาดู visibiliry แบบ public
ตัวอย่าง code

<?php
class FirstClass{
    public $name="Weerachit Muangma";//ถ้าเราไม่กำหนดนี่จะเป็นค่า defualt
    public $age;
    public function sayhi(){
        $name ="kob";//ตัวแปรของ method ไม่มองเป็น properties
        $sername ="2499";
        echo 'Hi';
        echo $this->name;
        echo '
'.$name;//เรียกใช้ได้เฉพาะใน method เท่านั้น
       
    }
    function saybye(){//การสร้างโดยไม่มีการกำหนด visibility แบบนี้ จะมองว่่าเป็น public
       
       echo "บ๊ายบาย";
    }
}

$a = new FirstClass();
echo $a->sayhi();
$a->name="KOb";
echo $a->sayhi();
echo $a->saybye();


คำอธิบาย

ค่าตัวแปรใน Class เราเรียก property ในตัวอย่าง Source ด้านบน "public $name" เราเรียก $name ว่าเป็น property ตัวหนี่งที่มีค่า visibiliry แบบ public
function ใน Class เราเรียกว่า method ในตัวอย่าง  "public function sayhi()" เราเรียกว่า method sayhi มีค่า visibiliry แบบ public เช่นกัน
ส่วนตัวแปรที่อยู่ใน method อย่างเช่น "$name ="kob";" เราถือว่าเป็นตัวแปรธรรมดา ไม่ถือว่าเป็น property และชื่อซ้ำกับ property ได้ไม่ซ้ำกัน เรียกใช้คนแบบตามตัวอย่าง

ส่วน visibility แบบ public นั้นสามารถเรียกใช้งานได้ทั้ง ใน Class และ นอก วิธีใช้ดังตัวอย่าง และถ้าเราไม่กำหนดคำนำหน้า ว่า public เขียนแบบลอยๆ มันจะถือว่าเป็น visibility แบบ public เสมอ

ตัวอย่าง visibiliry แบบ private

class FirstClass{
    public $name="Weerachit Muangma";//ถ้าเราไม่กำหนดนี่จะเป็นค่า defualt
    private $age=39;//การกำหนก visibility ให้เป้น private
    public function sayhi(){
        $name ="kob";//ตัวแปรของ method ไม่มองเป็น property
        $sername ="2499";
       // echo 'Hi';
       // echo $this->name;
       // echo '
'.$name;//เรียกใช้ได้เฉพาะใน method เท่านั้น
        echo 'อายุ'.$this->age;//เรียกใช้ private property
        echo '
';
        echo $this->SetAge();//เรียกใช้ private method
       
    }
    function saybye(){//การสร้างโดยไม่มีการกำหนด visibility แบบนี้ จะมองว่่าเป็น public
       
       echo "บ๊ายบาย";
    }
   
    private function SetAge(){
        return $this->age;
       
    }
}

$obj = new FirstClass();
//$obj->age=29;//error Fatal error: Uncaught Error: Cannot access private property FirstClass::$age ฟ้องว่าไม่สามารถ access age ซึ่่งเป็น private ได้
$obj->sayhi();
//$obj->SetAge();//Fatal error: Uncaught Error: Call to private method FirstClass::SetAge() from context 'ฟ้องว่าไม่สามารถ เรียก methos ที่เป็น private ได้

คำอธิบาย
visibility แบบ private จะใช้ได้เฉพาะใน Class ตัวเองเท่านั้น ไม่สามารถใช้ใน Class หรือเรียกใช้หรือกำหนดค่าจากภายนอกได้ ช่วยเรื่องความปลอดภัย และความซ้ำซ้อนของชื่อตัวแปรต่างๆ


ตัวอย่างนี้เรามาดู visibiliry แบบ protected

<?php
//visibilly แบบ  protected คล้ายกับ private ไม่สามารถใช้งานจากภายนอกได้ แต่สามารถสืบทอดได้ โดย extends
error_reporting(E_ALL);
class FirstClass{//ยกตัวอย่างเป็น class แม่
    protected $id="Protected Show";
    private $id2="Private Show";//property แบบที่กำหนด visibility เป็น private นั้นไม่สามารถ extends ได้
}
class SecondClass extends FirstClass{//ยกตัวอย่่างว่าเป้น class ลูก
    public function show(){
        echo $this->id;
        echo $this->id2;//จะไม่แสดงเนื่องจากไม่สามารถใช้ได้โดยการสืบทอด Undefined property: SecondClass::$id2
        echo $this->show2();
       
    }
   
    protected  function show2(){//เช่นเดียวกันกับ protected method ก็แสดงได้ใน class ที่ extends เท่านั้น
        echo "Show protected 2222";
    }
   
   
}


$obj = new SecondClass();
$obj->show();

//ถ้าลองใช้แบบนี้ว่ามันสามารถ protected ได้จริงหรือไม่

$obj2= new FirstClass();
// $obj2->id="x";// Uncaught Error: Cannot access protected property FirstClass::$id จะไม่สมารถ จัดการกับ property ที่เป็น protected ได้โดยตรง

คำอธิบาย

visibilly แบบ  protected คล้ายกับ private ไม่สามารถใช้งานจากภายนอกได้ แต่สามารถสืบทอดจาก Class อื่นได้ โดย extends ดังตัวอย่าง

ตัวอย่างการสืบทอด หรือ inheritance ดังนี้

ที่ file inheritance.php พิมพ์
<?php
//เรียกทดสอบผ่าน file male.php
class Human{
    public $name;
    public $sername;
    public $age;
    private $salary='10000';
   
    public function say(){
        return "HI".$this->name.'
salary='.$this->salary;

       
    }
    public function walk(){
        return "Walk";
    }
}

และที่ file male.php พิมพ์:

<?php
error_reporting(E_All);
include 'inheritance.php';
class Male extends Human{
    public function ShowText(){
        $this->name="Weerachit";//เรียก property จาก class Human ใน file 4-inheritance.php มาใช้
        $this->salary ="50000";//error ไม่มีค่า
        echo $this->say();//สั่งให้แสดงได้เลย เพราะสืบทอดมาจาก class Human ใน file 4-inheritance.php
    }
   
}

$obj = new Male();
$obj->ShowText();




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


<?php
error_reporting(E_ALL);
class Paramet{
    private $name;//property ใน class ไม่เดี่ยวกับ parameter ใน method แม้จะมีชื่อเดียวกัน
    private $sername;
    public function setValue($name='',$sername=''){
       
                $this->name=$name;
                $this->sername=$sername;
    }
   
    public function getValue(){
        return $this->name . ' -'.$this->sername;
    }
}
$obj = new Paramet();
//$obj->setValue();//Uncaught ArgumentCountError: Too few arguments to function Paramet::setValue() เนื่องจากไม่ใส่ parameter
//$obj->name="xxx";//ป้องกันการเข้าถึงแบบนี้
$obj->setValue('kob','Muangma');
echo $obj->getValue();



Method แบบ Construct และ Destruct


<?php
error_reporting(E_ALL);
//construct เขียนได้สองแบบคือ
//1 ให้ชื่อ method เหมือน ชื่อ class 2. ให้เขียนโดย method __construct แนะนำแบบที่  2 จะได้ไม่งง

//__destruct มักใช้ในการ disconnect mysql หรือ ปิดพวก duble tag เช่น </table>

class Myconst{
    private $name;
    private $sername;
   
    /* แบบ นี้ก้ได้ แต่ถ้า เขียนทั้งสองแบบใน class เดียวกัน มันจะถือว่า __construct เป็น default ของมันเสมอ
    public function Myconst(){
        echo "xxxx";
       
    }
    */
   
    public function __construct($name='',$sername=''){
        $this->name=$name;
        $this->sername=$sername;
       
    }
   
    public function getValue(){
        return $this->name . ' - ' . $this->sername;
       
    }
    public function __destruct(){//มักใช้กับการ disconnect mysql ทุกครั้ง ส่่วนอื่นก็มักไม่นิยมใช้กัน
        echo  '
 End';
    }

}

$obj = new Myconst('weerachit','muangma');//แค่เรากำหนดค่าใน method construct ค่าในนี้ก็จะแสดงออกมาโดยไม่ต้องเรียกใช้ method เลย และส่งค่าไปยัง method __construct ทันทีเลยไม่ต้องเรียก
echo $obj->getValue();

คำอธิบาย
method แบบ construct เขียนได้สองแบบ คือ 1 ตั้งชื่อ method ให้เหมือนกับชื่อ Class ก็ถือว่า method นั้นเป็น construct หรือ เขียน "function __construct" ก็ได้เหมือนกันแต่แนะนำให้ใช้แบบหลังจะได้ไม่งง และถ้าใช้ทั้งสองแบบพร้อมกันมันจะเห็นในรูปแบบที่สองเป็น construct เป็นหลัก
เพิ่มเติม
โดยมากใช้กับการ connect database และ disconnet จาก __construct และ __destruct ตามลำดับ



visibility แบบ Static

<?php

error_reporting(E_ALL);
class staticClass{
    public static $name="Weerachit";
    public static $sername="Muangma";
   
    public static function Main($name){
        echo staticClass::$sername;//เรียกใช้ใน class ไม่ต้องใช้ $this-> หรือ
        echo '</br>';
        echo self::$sername;//เหมือนกันกับ บรรทัดบน
        echo '</br>';
        echo $name;
    }
   

}

echo staticClass::$name;// การเรียกใช้ Class แบบ static ต้องเรียกแบบนี้
echo '</br>';
//หรือแบบนี้ก็ได้
$obj = new staticClass();
echo $obj::$name;
echo '</br>';

//การเรียก method แบบ static เรียกแบบนี้ได้เลยนะครับ

staticClass::Main('Weerachit muangma');

คำอธิบาย

การใช้ visibility แบบ static นั้นมีวิธีเรียกใช้ที่มากกว่าปกติคือ <classname>::<property or method>
และถ้าเรียกใช้ property ใน class ใช้ self::<property> แทน $this-><propertyname>ได้



abstract class


<?php
//abstract class ที่สืบทอด ต้องมี method ของ class ที่เหมือนกันทุกประการกับต้นแบบ Class ต้นแบบจะเขียนไว้เป็นโครงเปล่าๆไว้เท่านั้น และ visibility ต้องเป็น public เท่านั้น
// เหมาะสำหรับ ทำโครง Class แม่แบบ ให้ Class ลูกๆนั้นมีโครงสร้างที่เหมือนกัน
error_reporting(E_ALL);
abstract class Mom{
    abstract function say();
    abstract function walk();
   
}
class Child extends Mom{
   public function say(){
        echo "Hi";
    }
  /* private function walk(){ //ต้องเป็น public เท่านั้น
        echo "walk";
    }
    */
    public function walk(){
        echo "walk";
    }
   
}
$obj = new Child();
echo $obj->say();
echo '</br>';
echo $obj->walk();

คำอธิบาย
abstract class เป็นเหมือน class ต้นแบบซึ่ง class ที่สืบทอดต้องมี method ของ class ที่เหมือนกันทุกประการกับต้นแบบ Class ต้นแบบจะเขียนไว้เป็นโครงเปล่าๆไว้เท่านั้น และ visibility ต้องเป็น public เท่านั้น



Class แบบ interface

<?php
//interface คล้ายๆกับ กับ abstract แต่ต่างกันที่  ไม่ต้อง เขียน class
error_reporting(E_ALL);
interface Mom{
    public function say();
    public function walk();
   // private function ok(); แบบนี้ไม่ได้ต้องเป็น public อย่างเดียวเท่่านั้น
}

interface Dad{
    public function work();
}

class Human{
   
    public function __construct(){
       
        echo "Human </br>";
    }
}
class Child extends Human implements Mom,Dad{//ในการเรียกใช้ interface class ต้องใช้ implements แทน extend เรียกทีละหลายอันได้ แต่จะได้ใช้ไหมหว่่า ส่วน extends ใช้กับ class ธรรมดา
    //extends จะได้ทีละ class ส่วน implements ได้ทีละหลายๆ class
    public function say(){
        echo "Hi";
    }
    public function walk(){
        echo "walk";
    }
    public function work(){
        echo "work";
    }
   
}



$obj = new Child();
$obj->say();

คำอธิบาย
interface คล้ายๆกับ กับ abstract แต่ต่างกันที่  ไม่ต้อง เขียนคำว่า  class และ classลูกสามารถที่จะสืบทอดได้พร้อมกันหลายๆ class ในทีเดียวกัน ต่างจาก class แบบทั่วไปที่สืบทอด class แม่ได้ ทีละ class
« แก้ไขครั้งสุดท้าย: ตุลาคม 09, 2017, 04:20:06 pm โดย ผู้ดูแลระบบ »