PHP101 – OOP ขั้นสูง (Advanced OOP)

ใน Module นี้ เราจะมาเจาะลึกในหัวข้อที่เกี่ยวกับการเขียนโปรแกรมเชิงวัตถุ (OOP) ใน PHP ที่มีความซับซ้อนและมีประโยชน์มากยิ่งขึ้น เพื่อให้คุณสามารถออกแบบและพัฒนาแอปพลิเคชันที่มีโครงสร้างที่ดีและยืดหยุ่น

Namespaces

Namespaces ช่วยในการจัดระเบียบคลาส อินเทอร์เฟซ และฟังก์ชัน เพื่อป้องกันการชนกันของชื่อ (Naming Conflicts) เมื่อมีโค้ดจากหลายแหล่งที่มา

PHP
<?php

  namespace MyProject\Database;

  class Connection {
    public function connect() {
      return "Connected to MyProject Database";
    }
  }

  namespace AnotherProject\Database;

  class Connection {
    public function connect() {
      return "Connected to AnotherProject Database";
    }
  }

  use MyProject\Database\Connection as MyConnection;
  use AnotherProject\Database\Connection as AnotherConnection;

  $myConn = new MyConnection();
  echo $myConn->connect() . "<br>"; // Output: Connected to MyProject Database

  $anotherConn = new AnotherConnection();
  echo $anotherConn->connect(); // Output: Connected to AnotherProject Database

?>

Autoloading

Autoloading คือกลไกที่ช่วยให้ PHP สามารถโหลดไฟล์คลาสได้โดยอัตโนมัติเมื่อมีการใช้งานคลาส โดยที่คุณไม่ต้อง require หรือ include ไฟล์คลาสนั้นๆ ทุกครั้ง

spl_autoload_register()

ฟังก์ชัน spl_autoload_register() ใช้เพื่อลงทะเบียนฟังก์ชัน Autoloader ซึ่งจะถูกเรียกใช้เมื่อ PHP พยายามใช้คลาสที่ยังไม่ได้ถูกโหลด

PHP
<?php

  spl_autoload_register(function ($className) {
    $path = str_replace('\\', '/', $className) . '.php';
    if (file_exists($path)) {
      require $path;
    }
  });

  // สมมติว่ามีคลาส MyProject\Services\UserService อยู่ในไฟล์ MyProject/Services/UserService.php
  $userService = new \MyProject\Services\UserService();
  // PHP จะพยายามโหลดไฟล์ MyProject/Services/UserService.php โดยอัตโนมัติ

?>

Static Properties และ Methods

Static Properties และ Methods เป็นของคลาสโดยตรง ไม่ใช่ของ Instance ของคลาส สามารถเข้าถึงได้โดยไม่ต้องสร้าง Object ของคลาสนั้น

PHP
<?php

  class Counter {
    public static $count = 0;

    public static function increment() {
      self::$count++;
    }
  }

  Counter::increment();
  Counter::increment();
  echo "Count is: " . Counter::$count; // Output: Count is: 2

?>

Constants ของคลาส (Class Constants)

Constants ของคลาสเป็นค่าคงที่ที่ไม่สามารถเปลี่ยนแปลงได้หลังจากถูกกำหนด มักใช้สำหรับกำหนดค่าคงที่ที่เกี่ยวข้องกับคลาส

PHP
<?php

  class MathConstants {
    const PI = 3.14159;
    const E = 2.71828;
  }

  echo "ค่า PI คือ: " . MathConstants::PI . "<br>";
  echo "ค่า E คือ: " . MathConstants::E;

?>

Abstract Classes และ Methods

Abstract Classes ไม่สามารถนำมาสร้าง Object ได้โดยตรง มีไว้เพื่อเป็นแม่แบบให้คลาสลูกสืบทอด และสามารถมี Abstract Methods ซึ่งเป็น Methods ที่ไม่มี Body และคลาสลูกจะต้อง Implement Method เหล่านั้น

PHP
<?php

  abstract class Shape {
    abstract public function area();
    public function displayArea() {
      echo "พื้นที่คือ: " . $this->area() . "<br>";
    }
  }

  class Circle extends Shape {
    private $radius;

    public function __construct($radius) {
      $this->radius = $radius;
    }

    public function area() {
      return pi() * $this->radius * $this->radius;
    }
  }

  $circle = new Circle(5);
  $circle->displayArea(); // Output: พื้นที่คือ: 78.539816339745

?>

Interfaces

Interfaces กำหนดสัญญาว่าคลาสที่ Implement Interface นั้นจะต้องมี Methods ตามที่กำหนดไว้ Interfaces ไม่สามารถมี Properties ได้ และ Methods ใน Interface จะต้องเป็น public

PHP
<?php

  interface LoggerInterface {
    public function log($message);
  }

  class FileLogger implements LoggerInterface {
    private $filename;

    public function __construct($filename) {
      $this->filename = $filename;
    }

    public function log($message) {
      file_put_contents($this->filename, $message . "\n", FILE_APPEND);
    }
  }

  class DatabaseLogger implements LoggerInterface {
    public function log($message) {
      // โค้ดสำหรับบันทึกลงฐานข้อมูล
      echo "Logged to database: " . $message . "<br>";
    }
  }

  $fileLogger = new FileLogger("app.log");
  $fileLogger->log("Application started");

  $dbLogger = new DatabaseLogger();
  $dbLogger->log("User logged in");

?>

Traits

Traits เป็นกลไกสำหรับนำโค้ดจากคลาสหนึ่งไปใช้ในคลาสอื่นๆ โดยไม่มีการสืบทอด Traits ช่วยในการหลีกเลี่ยงปัญหา Multiple Inheritance ที่ PHP ไม่รองรับ

PHP
<?php

  trait Loggable {
    public function logMessage($message) {
      echo "Logging: " . $message . "<br>";
    }
  }

  class User {
    use Loggable;

    public $name;

    public function __construct($name) {
      $this->name = $name;
      $this->logMessage("User " . $name . " created");
    }
  }

  class Product {
    use Loggable;

    public $title;

    public function __construct($title) {
      $this->title = $title;
      $this->logMessage("Product " . $title . " added");
    }
  }

  $user = new User("Alice");
  $product = new Product("Laptop");

?>

Method Chaining

Method Chaining คือการเรียกใช้ Methods หลายๆ ตัวของ Object ต่อเนื่องกัน โดยแต่ละ Method จะ Return $this (Instance ของ Object เอง)

PHP
<?php

  class StringBuilder {
    private $string = "";

    public function append($str) {
      $this->string .= $str;
      return $this;
    }

    public function toUpper() {
      $this->string = strtoupper($this->string);
      return $this;
    }

    public function get() {
      return $this->string;
    }
  }

  $builder = new StringBuilder();
  $result = $builder->append("hello")->append(" world")->toUpper()->get();
  echo $result; // Output: HELLO WORLD

?>

กิจกรรมใน Module 12

  1. สร้าง Namespaces เพื่อจัดระเบียบคลาสของคุณ
  2. Implement ระบบ Autoloading สำหรับโหลดคลาสอัตโนมัติ
  3. ใช้ Static Properties และ Methods ในคลาส
  4. กำหนด Constants ให้กับคลาส
  5. สร้าง Abstract Class และคลาสลูกที่ Implement Abstract Methods
  6. สร้าง Interface และ Implement ในหลายๆ คลาส
  7. ใช้ Traits เพื่อนำโค้ดไปใช้ซ้ำในหลายคลาส
  8. (Optional) ลอง Implement Method Chaining ในคลาสของคุณ

ใน Module ถัดไป เราจะเรียนรู้เกี่ยวกับการจัดการข้อผิดพลาดและ Exception Handling ใน PHP เพื่อให้แอปพลิเคชันของคุณมีความเสถียรและสามารถจัดการกับสถานการณ์ที่ไม่คาดฝันได้อย่างเหมาะสมครับ!

ความคิดเห็น