📖 Bài Viết

Học PHP OOP siêu tốc: Từ zero đến biết dùng trong 10 phút

👁 12 lượt xem
Hướng dẫn lập trình hướng đối tượng trong PHP

Nếu bạn đã quen viết PHP theo kiểu thủ tục (procedural) — toàn hàm với biến rải khắp file — và giờ muốn nhảy sang OOP (Lập trình hướng đối tượng) nhưng ngại đọc tài liệu dài dòng, bài viết này dành cho bạn. Không lý thuyết hàn lâm, chỉ code và ví dụ thực tế.

OOP là gì, tại sao phải học?

Hiểu đơn giản: thay vì viết code rải rác, bạn gom dữ liệuhành vi liên quan vào chung một “khuôn” gọi là class. Từ khuôn đó, bạn tạo ra các object — giống như từ bản vẽ nhà, bạn xây được nhiều căn nhà cụ thể.

Lợi ích: code dễ tái sử dụng, dễ bảo trì, và gần như bắt buộc nếu bạn dùng các framework lớn như Laravel hay Symfony.

1. Class và Object — viên gạch đầu tiên

<?php
class NguoiDung {
    public string $ten;
    protected int $tuoi;
    private string $matKhau;

    public function __construct(string $ten, int $tuoi, string $matKhau) {
        $this->ten = $ten;
        $this->tuoi = $tuoi;
        $this->matKhau = $matKhau;
    }

    public function chao() {
        return "Xin chào, tôi là {$this->ten}, {$this->tuoi} tuổi";
    }
}

$user = new NguoiDung("An", 25, "123456");
echo $user->chao(); // Xin chào, tôi là An, 25 tuổi

Vài điểm cần nhớ:

  • class định nghĩa khuôn mẫu, new tạo ra object thực tế.
  • __construct() là hàm khởi tạo, tự động chạy khi bạn gọi new.
  • $this luôn trỏ đến chính object đang được thao tác.

2. Ba mức truy cập: public, protected, private

Từ khóaTruy cập được từ đâu
publicMọi nơi, kể cả bên ngoài class
protectedTrong class và các class con kế thừa
privateChỉ trong chính class đó

Nguyên tắc chung: mặc định nên để private hoặc protected, chỉ mở public cho những gì thực sự cần dùng từ bên ngoài. Đây chính là tinh thần của Encapsulation (đóng gói) — một trong bốn trụ cột của OOP.

3. Kế thừa — tái sử dụng code thông minh

class Admin extends NguoiDung {
    public array $quyen;

    public function __construct(string $ten, int $tuoi, string $matKhau, array $quyen) {
        parent::__construct($ten, $tuoi, $matKhau);
        $this->quyen = $quyen;
    }

    public function chao() {
        return parent::chao() . " - Tôi là Admin";
    }
}

$admin = new Admin("Bình", 30, "abc", ["xoa", "sua"]);
echo $admin->chao();

Admin extends NguoiDung nghĩa là Admin thừa hưởng toàn bộ thuộc tính và phương thức của NguoiDung, rồi có thể bổ sung hoặc ghi đè (override) thêm. parent:: dùng để gọi lại phiên bản gốc từ class cha.

4. Interface và Abstract Class — khi nào dùng cái nào?

interface CoTheBay {
    public function bay(): string;
}

abstract class DongVat {
    abstract public function keu(): string;

    public function gioiThieu() {
        return "Tôi kêu: " . $this->keu();
    }
}

class Chim extends DongVat implements CoTheBay {
    public function keu(): string {
        return "chíp chíp";
    }
    public function bay(): string {
        return "Bay vút lên trời";
    }
}

$chim = new Chim();
echo $chim->gioiThieu();
echo $chim->bay();

Phân biệt nhanh:

  • Interface: chỉ quy định “phải có method gì”, không viết logic bên trong. Một class có thể implements nhiều interface cùng lúc.
  • Abstract class: có thể vừa chứa method đã viết sẵn, vừa có method bắt buộc class con phải tự triển khai (abstract). Một class chỉ extends được một abstract class.

5. Static và Constant — dùng khi không cần tạo object

class ToanHoc {
    const PI = 3.14159;
    public static int $soLuong = 0;

    public static function congHaiSo(int $a, int $b): int {
        self::$soLuong++;
        return $a + $b;
    }
}

echo ToanHoc::PI;
echo ToanHoc::congHaiSo(2, 3); // 5

Gọi trực tiếp qua tên class bằng ::, không cần new. Thích hợp cho các hàm tiện ích (utility) hoặc hằng số dùng chung.

6. Traits — chia sẻ code không qua kế thừa

trait Log {
    public function log($msg) {
        echo "[LOG] $msg\n";
    }
}

class DonHang {
    use Log;
}

$don = new DonHang();
$don->log("Đơn hàng đã tạo");

PHP không cho kế thừa nhiều class cùng lúc (không như một số ngôn ngữ khác), nên trait là giải pháp để “nhét” thêm chức năng dùng chung vào nhiều class khác nhau mà không cần quan hệ cha-con.

7. Magic Methods — những hàm “phép thuật”

class SanPham {
    private array $data = [];

    public function __get($ten) { return $this->data[$ten] ?? null; }
    public function __set($ten, $value) { $this->data[$ten] = $value; }
    public function __toString() { return "SanPham: " . json_encode($this->data); }
}

$sp = new SanPham();
$sp->ten = "Laptop";
echo $sp; // SanPham: {"ten":"Laptop"}

PHP tự động gọi các hàm này trong những tình huống đặc biệt: __get/__set khi truy cập thuộc tính không tồn tại trực tiếp, __toString khi object được ép thành chuỗi (ví dụ dùng trong echo).

Bốn trụ cột OOP — tóm gọn lại

  • Encapsulation (Đóng gói): giấu dữ liệu nội bộ bằng private/protected, chỉ để lộ những gì cần thiết.
  • Inheritance (Kế thừa): dùng extends để tái sử dụng và mở rộng code từ class cha.
  • Polymorphism (Đa hình): cùng một method nhưng mỗi class con lại thực thi khác nhau (override).
  • Abstraction (Trừu tượng): định nghĩa “cái gì cần có” qua interface/abstract class, để chi tiết triển khai cho từng class con.

Bước tiếp theo

Lý thuyết chỉ thực sự “ngấm” khi bạn bắt tay code. Gợi ý một vài mini project để luyện tập:

  • Hệ thống quản lý sản phẩm với interface cho các loại giảm giá khác nhau
  • Giỏ hàng dùng trait để log lại lịch sử thao tác
  • Hệ thống người dùng với phân quyền qua abstract class

Chọn một cái, bắt đầu viết, và bạn sẽ thấy OOP trong PHP không hề đáng sợ như tưởng tượng.

🏷️ Tags: Lập trình PHP PHP
Chia sẻ: Facebook Twitter