Sau khi hoàn thành Mini Project CRUD, bước tiếp theo là học OOP (Object-Oriented Programming) – Lập trình hướng đối tượng trong PHP. OOP là phương pháp lập trình hiện đại, giúp code dễ bảo trì, tái sử dụng và mở rộng. Từ dự án nhỏ đến framework lớn như Laravel, Symfony đều xây dựng trên nền tảng OOP.
1. OOP là gì?
OOP (Object-Oriented Programming) là phương pháp lập trình tổ chức code thành các đối tượng (Objects) – những thực thể có thuộc tính và hành vi riêng.
1.1. So sánh Procedural vs OOP
<?php
// ❌ PROCEDURAL - Code rời rạc, khó bảo trì
$user_name = "Nguyễn Văn A";
$user_email = "a@email.com";
$user_age = 20;
function getUserInfo($name, $email, $age) {
return "$name - $email - $age tuổi";
}
echo getUserInfo($user_name, $user_email, $user_age);
// ✅ OOP - Code có tổ chức, dễ quản lý
class User {
public $name;
public $email;
public $age;
public function getInfo() {
return "$this->name - $this->email - $this->age tuổi";
}
}
$user = new User();
$user->name = "Nguyễn Văn A";
$user->email = "a@email.com";
$user->age = 20;
echo $user->getInfo();
?>1.2. Tại sao học OOP?
- ✅ Tái sử dụng code: Viết 1 lần, dùng nhiều nơi
- ✅ Dễ bảo trì: Sửa 1 chỗ, ảnh hưởng đúng phạm vi
- ✅ Mở rộng dễ: Thêm tính năng không ảnh hưởng code cũ
- ✅ Bảo mật: Ẩn dữ liệu nhạy cảm (Encapsulation)
- ✅ Teamwork: Nhiều người code cùng lúc
- ✅ Framework: Laravel, Symfony, WordPress… đều dùng OOP
2. Class là gì?
Class (Lớp) là bản thiết kế (blueprint) để tạo ra các đối tượng. Giống như bản vẽ nhà – từ 1 bản vẽ có thể xây nhiều ngôi nhà.
<?php
// Khai báo class
class Car {
// Properties (thuộc tính)
public $brand;
public $color;
public $speed;
// Methods (phương thức)
public function start() {
echo "Xe $this->brand đang khởi động...";
}
public function accelerate() {
$this->speed += 10;
echo "Tăng tốc! Tốc độ: $this->speed km/h";
}
}
?>Giải thích:
class Car– Tên class (viết hoa chữ cái đầu)public $brand– Thuộc tính (biến trong class)public function start()– Phương thức (hàm trong class)$this– Tham chiếu đến object hiện tại
3. Object là gì?
Object (Đối tượng) là thực thể cụ thể được tạo từ Class. Từ 1 class có thể tạo nhiều objects.
<?php
class Car {
public $brand;
public $color;
public function getInfo() {
return "Xe $this->brand màu $this->color";
}
}
// Tạo object từ class (gọi là instance)
$car1 = new Car();
$car1->brand = "Toyota";
$car1->color = "Đỏ";
$car2 = new Car();
$car2->brand = "Honda";
$car2->color = "Trắng";
echo $car1->getInfo(); // Xe Toyota màu Đỏ
echo $car2->getInfo(); // Xe Honda màu Trắng
?>Điểm quan trọng:
- ✅ Mỗi object độc lập – thay đổi
$car1không ảnh hưởng$car2 - ✅ Dùng toán tử
->để truy cập properties và methods - ✅ Từ khóa
newđể tạo object mới
4. Properties (Thuộc tính)
Properties là các biến bên trong class, lưu trữ dữ liệu của object.
4.1. Khai báo Properties
<?php
class Student {
// Khai báo properties
public $name;
public $age;
public $email;
public $gpa = 0.0; // Giá trị mặc định
// Có thể khai báo nhiều cùng lúc
public $address, $phone;
}
// Sử dụng
$student = new Student();
$student->name = "Nguyễn Văn A";
$student->age = 20;
$student->email = "a@email.com";
echo $student->name; // Nguyễn Văn A
echo $student->gpa; // 0.0 (giá trị mặc định)
?>4.2. Access Modifiers (Phạm vi truy cập)
<?php
class User {
public $name; // Truy cập mọi nơi
protected $email; // Chỉ trong class và class con
private $password; // Chỉ trong class này
public function setPassword($pass) {
$this->password = password_hash($pass, PASSWORD_DEFAULT);
}
public function checkPassword($pass) {
return password_verify($pass, $this->password);
}
}
$user = new User();
$user->name = "An"; // OK - public
$user->setPassword("secret123"); // OK - dùng method
// $user->password = "123"; // ❌ Lỗi - private không truy cập được
?>| Modifier | Trong class | Class con | Bên ngoài |
|---|---|---|---|
public | ✅ | ✅ | ✅ |
protected | ✅ | ✅ | ❌ |
private | ✅ | ❌ | ❌ |
5. Methods (Phương thức)
Methods là các hàm bên trong class, định nghĩa hành vi của object.
5.1. Khai báo Methods
<?php
class Calculator {
public $result = 0;
// Method không tham số
public function reset() {
$this->result = 0;
}
// Method có tham số
public function add($a, $b) {
$this->result = $a + $b;
return $this->result;
}
// Method trả về giá trị
public function getResult() {
return $this->result;
}
// Method gọi method khác
public function addAndShow($a, $b) {
$this->add($a, $b);
echo "Kết quả: " . $this->getResult();
}
}
$calc = new Calculator();
echo $calc->add(5, 3); // 8
$calc->addAndShow(10, 20); // Kết quả: 30
?>5.2. $this – Tham chiếu đến object hiện tại
<?php
class BankAccount {
public $balance = 0;
public function deposit($amount) {
// $this trỏ đến object đang gọi method
$this->balance += $amount;
return $this; // Trả về chính object (method chaining)
}
public function withdraw($amount) {
if ($amount <= $this->balance) {
$this->balance -= $amount;
} else {
echo "Số dư không đủ!";
}
return $this;
}
public function getBalance() {
return $this->balance;
}
}
$account = new BankAccount();
// Method chaining - gọi liên tiếp
$account->deposit(1000)
->deposit(500)
->withdraw(300);
echo $account->getBalance(); // 1200
?>6. Ví dụ thực tế
6.1. Class User – Quản lý người dùng
<?php
class User {
// Properties
public $id;
public $name;
public $email;
private $password;
public $created_at;
// Setter cho password (mã hóa)
public function setPassword($password) {
$this->password = password_hash($password, PASSWORD_DEFAULT);
}
// Kiểm tra mật khẩu
public function checkPassword($password) {
return password_verify($password, $this->password);
}
// Lấy thông tin user
public function getInfo() {
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'created_at' => $this->created_at
];
}
// Hiển thị thông tin
public function display() {
echo "<div class='user-card'>";
echo "<h3>$this->name</h3>";
echo "<p>Email: $this->email</p>";
echo "<p>ID: $this->id</p>";
echo "</div>";
}
}
// Sử dụng
$user = new User();
$user->id = 1;
$user->name = "Nguyễn Văn A";
$user->email = "a@email.com";
$user->setPassword("password123");
$user->created_at = date("Y-m-d H:i:s");
// Kiểm tra mật khẩu
if ($user->checkPassword("password123")) {
echo "Đăng nhập thành công!";
}
// Hiển thị thông tin
$user->display();
// Lấy mảng thông tin
$info = $user->getInfo();
print_r($info);
?>6.2. Class Product – Quản lý sản phẩm
<?php
class Product {
public $id;
public $name;
public $price;
public $quantity;
public $category;
// Tính tổng giá trị
public function getTotalValue() {
return $this->price * $this->quantity;
}
// Kiểm tra còn hàng
public function inStock() {
return $this->quantity > 0;
}
// Giảm giá
public function applyDiscount($percent) {
$discount = $this->price * ($percent / 100);
$this->price -= $discount;
return $this->price;
}
// Format giá tiền
public function formatPrice() {
return number_format($this->price, 0, ',', '.') . ' VNĐ';
}
// Hiển thị thông tin
public function display() {
$status = $this->inStock() ? "Còn hàng" : "Hết hàng";
echo "<div class='product'>";
echo "<h3>$this->name</h3>";
echo "<p>Giá: " . $this->formatPrice() . "</p>";
echo "<p>Số lượng: $this->quantity</p>";
echo "<p>Trạng thái: $status</p>";
echo "<p>Tổng giá trị: " . number_format($this->getTotalValue(), 0, ',', '.') . " VNĐ</p>";
echo "</div>";
}
}
// Sử dụng
$product = new Product();
$product->id = 1;
$product->name = "Laptop Dell XPS 13";
$product->price = 25000000;
$product->quantity = 5;
$product->category = "Laptop";
echo $product->formatPrice(); // 25,000,000 VNĐ
echo $product->getTotalValue(); // 125000000
// Giảm giá 10%
$product->applyDiscount(10);
echo $product->formatPrice(); // 22,500,000 VNĐ
// Hiển thị
$product->display();
?>6.3. Class ShoppingCart – Giỏ hàng
<?php
class ShoppingCart {
private $items = [];
// Thêm sản phẩm
public function addItem($product, $quantity = 1) {
$item = [
'product' => $product,
'quantity' => $quantity
];
$this->items[] = $item;
}
// Đếm số mặt hàng
public function getItemCount() {
return count($this->items);
}
// Tính tổng tiền
public function getTotal() {
$total = 0;
foreach ($this->items as $item) {
$total += $item['product']->price * $item['quantity'];
}
return $total;
}
// Hiển thị giỏ hàng
public function display() {
if (empty($this->items)) {
echo "Giỏ hàng trống";
return;
}
echo "<h2>Giỏ hàng của bạn</h2>";
echo "<table>";
echo "<tr><th>Sản phẩm</th><th>Giá</th><th>SL</th><th>Thành tiền</th></tr>";
foreach ($this->items as $item) {
$product = $item['product'];
$quantity = $item['quantity'];
$subtotal = $product->price * $quantity;
echo "<tr>";
echo "<td>{$product->name}</td>";
echo "<td>" . number_format($product->price) . "</td>";
echo "<td>{$quantity}</td>";
echo "<td>" . number_format($subtotal) . " VNĐ</td>";
echo "</tr>";
}
echo "<tr><td colspan='3'><strong>Tổng cộng</strong></td>";
echo "<td><strong>" . number_format($this->getTotal()) . " VNĐ</strong></td></tr>";
echo "</table>";
}
}
// Sử dụng
$product1 = new Product();
$product1->name = "Laptop";
$product1->price = 15000000;
$product2 = new Product();
$product2->name = "Chuột";
$product2->price = 200000;
$cart = new ShoppingCart();
$cart->addItem($product1, 1);
$cart->addItem($product2, 2);
echo "Số sản phẩm: " . $cart->getItemCount(); // 2
echo "Tổng tiền: " . number_format($cart->getTotal()); // 15,400,000
$cart->display();
?>7. Kiểm tra object và class
<?php
class Car {
public $brand;
}
$car = new Car();
$car->brand = "Toyota";
// Kiểm tra có phải object không
var_dump(is_object($car)); // bool(true)
// Lấy tên class
echo get_class($car); // Car
// Kiểm tra object thuộc class nào
var_dump($car instanceof Car); // bool(true)
// Kiểm tra property tồn tại
var_dump(property_exists($car, 'brand')); // bool(true)
var_dump(property_exists($car, 'color')); // bool(false)
// Kiểm tra method tồn tại
var_dump(method_exists($car, 'start')); // bool(false)
// Lấy danh sách properties
$props = get_object_vars($car);
print_r($props); // Array ( [brand] => Toyota )
// Lấy danh sách methods
$methods = get_class_methods('Car');
print_r($methods);
?>8. Best Practices
8.1. Quy tắc đặt tên
<?php
// ✅ Tên class: PascalCase (viết hoa chữ cái đầu mỗi từ)
class UserAccount { }
class ShoppingCart { }
// ✅ Tên property/method: camelCase
class Product {
public $productName;
public $unitPrice;
public function getDiscountPrice() { }
public function calculateTotalValue() { }
}
// ❌ Sai
class user_account { } // Không dùng snake_case cho class
class product {
public $ProductName; // Không viết hoa property
public function Get_Price() { } // Không viết hoa hoặc dùng underscore
}
?>8.2. Một class một file
<?php
// File: User.php
class User {
// ...
}
// File: Product.php
class Product {
// ...
}
// File: index.php
require_once 'User.php';
require_once 'Product.php';
$user = new User();
$product = new Product();
?>8.3. Properties nên là private/protected
<?php
class User {
// ✅ Tốt - Dùng private với getter/setter
private $email;
public function setEmail($email) {
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
$this->email = $email;
} else {
throw new Exception("Email không hợp lệ");
}
}
public function getEmail() {
return $this->email;
}
// ❌ Tránh - Public cho phép gán bừa
public $password; // Ai cũng gán được, không an toàn
}
?>Tóm tắt
Qua bài này bạn đã nắm được:
- ✅ OOP: Lập trình hướng đối tượng – tổ chức code thành objects
- ✅ Class: Bản thiết kế (blueprint) để tạo objects
- ✅ Object: Thực thể cụ thể được tạo từ class bằng từ khóa
new - ✅ Properties: Biến bên trong class, lưu dữ liệu của object
- ✅ Methods: Hàm bên trong class, định nghĩa hành vi của object
- ✅ $this: Tham chiếu đến object hiện tại
- ✅ Access Modifiers: public (mọi nơi), protected (class + con), private (chỉ trong class)
- ✅ Toán tử ->: Truy cập properties và methods của object
- ✅ Method Chaining: Return
$thisđể gọi method liên tiếp
Bài tiếp theo, bạn sẽ học về Constructor và Destructor – khởi tạo và hủy object.
🎯 Bài tập thực hành
- Bài 1: Tạo class
Bookvới properties: title, author, price, pages. Tạo methods: getInfo(), applyDiscount($percent), isExpensive() (giá > 500k). - Bài 2: Tạo class
BankAccountvới private property balance. Tạo methods: deposit($amount), withdraw($amount), getBalance(). Validate số tiền phải > 0. - Bài 3: Tạo class
Studentvới properties: name, email, scores (mảng điểm). Tạo methods: addScore($score), getAverage(), getGrade() (A/B/C/D/F).
Gợi ý Bài 1:
<?php
class Book {
public $title;
public $author;
public $price;
public $pages;
public function getInfo() {
return "$this->title - Tác giả: $this->author - Giá: " . number_format($this->price) . " VNĐ";
}
public function applyDiscount($percent) {
$this->price -= $this->price * ($percent / 100);
return $this->price;
}
public function isExpensive() {
return $this->price > 500000;
}
}
$book = new Book();
$book->title = "Lập trình PHP";
$book->author = "Nguyễn Văn A";
$book->price = 600000;
$book->pages = 500;
echo $book->getInfo();
echo $book->isExpensive() ? "Sách đắt" : "Sách rẻ";
$book->applyDiscount(10); // Giảm 10%
?>Gợi ý Bài 2:
<?php
class BankAccount {
private $balance = 0;
public function deposit($amount) {
if ($amount <= 0) {
echo "Số tiền phải > 0";
return false;
}
$this->balance += $amount;
return true;
}
public function withdraw($amount) {
if ($amount <= 0) {
echo "Số tiền phải > 0";
return false;
}
if ($amount > $this->balance) {
echo "Số dư không đủ";
return false;
}
$this->balance -= $amount;
return true;
}
public function getBalance() {
return $this->balance;
}
}
$account = new BankAccount();
$account->deposit(1000000);
$account->withdraw(300000);
echo $account->getBalance(); // 700000
?>