Lớp trừu tượng (abstract class) và interface trong PHP
Trong bài này, chúng ta sẽ tìm hiểu về lớp trừu tượng (abstract class) và interface...
Kết quả sẽ mở trong tab mới, giới hạn trong website này.
Truy cập nhanh
Tìm kiếm gần đây
Nếu máy chưa có môi trường chạy PHP, hãy xem hướng dẫn cài đặt XAMPP trên Góc Học IT. Sau bài Cài đặt XAMPP và tổ chức mã nguồn PHP, bạn đã biết đặt dự án trong htdocs và mở trang PHP qua localhost. Bây giờ, hãy thử làm một website bán hàng có hai […]
Nếu máy chưa có môi trường chạy PHP, hãy xem hướng dẫn cài đặt XAMPP trên Góc Học IT. Sau bài Cài đặt XAMPP và tổ chức mã nguồn PHP, bạn đã biết đặt dự án trong htdocs và mở trang PHP qua localhost. Bây giờ, hãy thử làm một website bán hàng có hai trang là Trang chủ và Sản phẩm. Cả hai cần cùng một menu, chân trang và giao diện CSS.
Giả sử bạn đã chép menu vào cả hai trang. Khi đổi tên mục “Sản phẩm” thành “Danh mục sản phẩm”, bạn phải sửa ở cả hai nơi. Nếu tách menu thành một file dùng chung, bạn chỉ cần sửa file đó. Đây là cách tổ chức mã nguồn PHP để việc cập nhật giao diện đơn giản hơn.
Nếu cài XAMPP ở vị trí mặc định trên Windows, hãy tạo thư mục banhang trong C:\xampp\htdocs. Mở thư mục banhang bằng Visual Studio Code và tạo các file sau.

banhang/
├── index.php
├── includes/
│ ├── header.php
│ ├── navbar.php
│ └── footer.php
├── pages/
│ └── san-pham.php
└── assets/
└── css/
└── style.css| Vị trí | Vai trò |
|---|---|
index.php | Hiển thị trang chủ. |
pages/ | Chứa các trang nội dung như Sản phẩm, Giới thiệu hoặc Liên hệ. |
includes/ | Chứa các phần được ghép vào nhiều trang, như menu và chân trang. |
assets/ | Chứa các tài nguyên trình duyệt tải trực tiếp. Khi cần, có thể thêm assets/js/ và assets/img/. |
Ví dụ này dùng dữ liệu mẫu trong PHP, vì vậy bạn chỉ cần bật Apache trong XAMPP Control Panel. Khi website có cơ sở dữ liệu, có thể gom các thiết lập kết nối vào nhóm file cấu hình. Khi triển khai, hãy giữ mật khẩu và khóa API ngoài thư mục web công khai và kho Git.
includes/header.phpFile này mở tài liệu HTML, hiển thị tiêu đề trên tab trình duyệt và liên kết đến CSS. Mỗi trang sẽ đặt biến $pageTitle trước khi nạp file.
<!doctype html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?= htmlspecialchars($pageTitle, ENT_QUOTES, 'UTF-8') ?> | Cửa hàng laptop</title>
<link rel="stylesheet" href="/banhang/assets/css/style.css">
</head>
<body>Cú pháp <?= ... ?> in giá trị ra HTML. Hàm htmlspecialchars() giúp trình duyệt hiển thị các ký tự như < và & dưới dạng văn bản trong tiêu đề.
includes/navbar.php<nav aria-label="Điều hướng chính">
<a href="/banhang/">Trang chủ</a>
<a href="/banhang/pages/san-pham.php">Sản phẩm</a>
</nav>includes/footer.phpChân trang đóng hai thẻ body và html đã mở trong header.php.
<footer>
<p>Cửa hàng laptop</p>
</footer>
</body>
</html>index.php<?php
$pageTitle = 'Trang chủ';
require __DIR__ . '/includes/header.php';
require __DIR__ . '/includes/navbar.php';
?>
<main>
<h1>Chào mừng đến với cửa hàng laptop</h1>
<p>Xem các mẫu laptop và giá tại trang Sản phẩm.</p>
</main>
<?php require __DIR__ . '/includes/footer.php'; ?>Mở http://localhost/banhang/. Với cấu hình XAMPP thông thường, Apache sẽ dùng index.php làm trang mặc định của thư mục. PHP xử lý các file theo thứ tự xuất hiện trong mã nguồn. Trình duyệt nhận một tài liệu HTML gồm phần đầu trang, menu, nội dung chính và chân trang.
pages/san-pham.phpTrang này chuẩn bị tên và giá sản phẩm ở đầu file. Phần trong thẻ <main> chỉ duyệt dữ liệu và hiển thị. Cách sắp xếp này giúp bạn tìm chỗ sửa giá ngay cả khi phần HTML dài hơn.
<?php
$pageTitle = 'Sản phẩm';
$products = [
['name' => 'Laptop Dell', 'price' => 15000000],
['name' => 'Laptop Lenovo', 'price' => 18500000],
];
require __DIR__ . '/../includes/header.php';
require __DIR__ . '/../includes/navbar.php';
?>
<main>
<h1>Danh sách sản phẩm</h1>
<ul>
<?php foreach ($products as $product): ?>
<li>
<?= htmlspecialchars($product['name'], ENT_QUOTES, 'UTF-8') ?>
· <?= number_format($product['price'], 0, ',', '.') ?> ₫
</li>
<?php endforeach; ?>
</ul>
</main>
<?php require __DIR__ . '/../includes/footer.php'; ?>Bấm Sản phẩm trên menu hoặc mở http://localhost/banhang/pages/san-pham.php. Giá của Laptop Dell sẽ hiển thị là 15.000.000 ₫.
assets/css/style.cssbody {
margin: 0;
font: 1rem/1.6 Arial, sans-serif;
color: #1e293b;
}
nav {
display: flex;
gap: 1rem;
padding: 1rem 1.5rem;
background: #0f766e;
}
nav a {
color: white;
}
main,
footer {
padding: 1rem 1.5rem;
}
footer {
background: #f1f5f9;
}Tải lại cả hai trang. Nếu menu ở cả hai trang đều có nền xanh, trình duyệt đã tải cùng một file CSS từ hai URL trang khác nhau.
Hai dòng dưới đây có vẻ giống nhau vì đều chứa dấu /. Chúng được xử lý ở hai nơi khác nhau.
| Đoạn mã | Ai xử lý? | Đường dẫn được tính từ đâu? |
|---|---|---|
require __DIR__ . '/../includes/header.php'; | PHP | Từ thư mục chứa file đang viết, tức pages/ trong ví dụ này. |
href="/banhang/assets/css/style.css" | Trình duyệt | Từ gốc của website, tức http://localhost/ trong ví dụ này. |
__DIR__ là đường dẫn trên máy chủ đến thư mục chứa file PHP đang dùng hằng đó. Trong index.php, nó trỏ tới C:\xampp\htdocs\banhang, nên có thể đi thẳng vào includes/. Trong pages/san-pham.php, nó trỏ tới C:\xampp\htdocs\banhang\pages. Dấu .. đưa đường dẫn lên thư mục cha banhang/ rồi mới vào includes/.
Đối với CSS, trình duyệt đọc URL trong thẻ <link> và gửi một yêu cầu riêng. Dấu / ở đầu /banhang/assets/css/style.css khiến URL bắt đầu từ gốc website trên cả hai trang. Nếu viết href="assets/css/style.css", trình duyệt sẽ tìm trong /banhang/assets/ ở trang chủ, nhưng sẽ tìm trong /banhang/pages/assets/ ở trang sản phẩm. Nếu đổi tên thư mục dự án, hãy cập nhật phần /banhang/ trong các URL dùng chung.
include, require và _once?| Câu lệnh | Nếu file không nạp được | Nếu file đã được nạp trong cùng lần chạy |
|---|---|---|
include | PHP phát cảnh báo và có thể tiếp tục chạy. | Có thể nạp lại. |
require | PHP báo lỗi. Quá trình thực thi sẽ dừng nếu lỗi không được xử lý. | Có thể nạp lại. |
include_once | Có hành vi như include. | Bỏ qua lần nạp tiếp theo. |
require_once | Có hành vi như require. | Bỏ qua lần nạp tiếp theo. |
Ví dụ dùng require vì mỗi thành phần giao diện là một phần bắt buộc và mỗi trang gọi nó đúng một lần. Hậu tố _once hữu ích khi nhiều file cùng nạp một thư viện chứa hàm hoặc lớp. PHP sẽ bỏ qua lần nạp tiếp theo trong cùng lần chạy, giúp tránh khai báo trùng.
includes/navbar.php. Tải lại cả hai trang và kiểm tra menu đã đổi ở cả hai nơi.pages/san-pham.php, tạm bỏ .. ở dòng nạp header. Đọc đường dẫn PHP báo lỗi, xác định nó đã tìm thư mục includes/ ở đâu rồi khôi phục dòng đúng.header.php thành assets/css/style.css. Mở tab Network trong công cụ nhà phát triển, tải lại trang sản phẩm và tìm yêu cầu CSS trả về 404. Sau đó khôi phục URL bắt đầu bằng /banhang/.pages/lien-he.php, đặt tiêu đề riêng, nạp ba thành phần giao diện dùng chung và thêm liên kết vào menu. Kiểm tra có thể chuyển qua lại giữa cả ba trang.Khi thêm một trang mới, hãy bắt đầu bằng phần nội dung riêng của trang đó. Phần giao diện xuất hiện ở nhiều nơi có thể đưa vào includes/. Khi gặp lỗi đường dẫn, hãy xác định trước dòng đó do PHP hay trình duyệt xử lý.