FULL UPGRADE SHOP PHP 2026
MỤC TIÊU
Nâng cấp shop PHP mini thành:
MVC architecture
PWA giống app mobile
UI hiện đại kiểu TikTok Shop/Shopee
Responsive mobile cực đẹp
Dark mode
AJAX realtime
API JSON
Upload ảnh thật
WebP optimization
CDN + cache
One page checkout
Thanh toán QR tự động
Voucher system
Theo dõi vận đơn
Dashboard thống kê
Export Excel
SEO chuẩn Google
Bảo mật production
1. CẤU TRÚC THƯ MỤC MỚI
shop/
├── app/
│ ├── Controllers/
│ ├── Models/
│ ├── Views/
│ ├── Middleware/
│ ├── Services/
│ ├── Helpers/
│ └── Core/
│
├── bootstrap/
├── config/
├── public/
│ ├── assets/
│ ├── uploads/
│ ├── api/
│ ├── manifest.json
│ └── service-worker.js
│
├── routes/
├── storage/
├── vendor/
└── sql/
2. .ENV CONFIG
.env
APP_NAME=Shop Online
APP_URL=https://domain.com
DB_HOST=localhost
DB_NAME=shopdb
DB_USER=root
DB_PASS=
APP_DEBUG=true
3. AUTOLOAD
composer.json
{
"autoload": {
"psr-4": {
"App\\": "app/"
}
}
}
Run:
composer dump-autoload
4. ROUTER
routes/web.php
<?php
use App\Controllers\HomeController;
use App\Controllers\ProductController;
$router->get('/', [HomeController::class, 'index']);
$router->get('/product/{slug}', [ProductController::class, 'show']);
5. BASE CONTROLLER
app/Core/Controller.php
<?php
namespace App\Core;
class Controller {
protected function view($view, $data = []) {
extract($data);
require __DIR__ . '/../Views/' . $view . '.php';
}
}
6. DATABASE CLASS
app/Core/Database.php
<?php
namespace App\Core;
use PDO;
class Database {
private static $pdo;
public static function connect() {
if (!self::$pdo) {
self::$pdo = new PDO(
"mysql:host=" . $_ENV['DB_HOST'] . ";dbname=" . $_ENV['DB_NAME'] . ";charset=utf8mb4",
$_ENV['DB_USER'],
$_ENV['DB_PASS']
);
self::$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
return self::$pdo;
}
}
7. PRODUCT MODEL
app/Models/Product.php
<?php
namespace App\Models;
use App\Core\Database;
class Product {
public static function latest() {
return Database::connect()
->query("SELECT * FROM products ORDER BY id DESC")
->fetchAll();
}
public static function findBySlug($slug) {
$stmt = Database::connect()->prepare(
"SELECT * FROM products WHERE slug=? LIMIT 1"
);
$stmt->execute([$slug]);
return $stmt->fetch();
}
}
8. PRODUCT CONTROLLER
app/Controllers/ProductController.php
<?php
namespace App\Controllers;
use App\Core\Controller;
use App\Models\Product;
class ProductController extends Controller {
public function show($slug) {
$product = Product::findBySlug($slug);
if (!$product) {
http_response_code(404);
die('404');
}
return $this->view('product/show', compact('product'));
}
}
9. UPLOAD ẢNH THẬT
public/uploads/products
New-Item -ItemType Directory -Force -Path "public/uploads/products"
Upload image
$dir = __DIR__ . '/../../public/uploads/products/';
if (!empty($_FILES['image']['name'])) {
$ext = strtolower(pathinfo(
$_FILES['image']['name'],
PATHINFO_EXTENSION
));
$allow = ['jpg','jpeg','png','webp'];
if (in_array($ext, $allow)) {
$filename = uniqid() . '.' . $ext;
move_uploaded_file(
$_FILES['image']['tmp_name'],
$dir . $filename
);
$image_url = '/uploads/products/' . $filename;
}
}
10. AUTO WEBP
$img = imagecreatefromjpeg($source);
imagewebp($img, $destination, 80);
11. LAZY LOAD + RESPONSIVE IMAGE
<img
loading="lazy"
decoding="async"
src="<?= $product['image_url'] ?>"
alt=""
>
12. CDN TỐI ƯU
Cloudflare
bật Brotli
bật cache everything
bật Polish WebP
bật Rocket Loader
13. PWA APP
public/manifest.json
{
"name": "Shop Online",
"short_name": "Shop",
"display": "standalone",
"start_url": "/",
"theme_color": "#ff4f9a",
"background_color": "#ffffff",
"icons": [
{
"src": "/assets/icon-192.png",
"sizes": "192x192",
"type": "image/png"
}
]
}
14. SERVICE WORKER
public/service-worker.js
self.addEventListener('install', e => {
self.skipWaiting();
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
return response || fetch(event.request);
})
);
});
15. REGISTER SERVICE WORKER
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js');
}
</script>
16. DARK MODE
CSS
:root {
--bg:#fff;
--text:#111;
}
.dark {
--bg:#0f172a;
--text:#fff;
}
body {
background:var(--bg);
color:var(--text);
}
JS
const themeBtn = document.querySelector('#themeBtn');
if(localStorage.getItem('theme') === 'dark') {
document.body.classList.add('dark');
}
themeBtn.onclick = () => {
document.body.classList.toggle('dark');
localStorage.setItem(
'theme',
document.body.classList.contains('dark')
? 'dark'
: 'light'
);
};
17. AJAX SEARCH
API
public/api/search.php
<?php
header('Content-Type: application/json');
$q = $_GET['q'] ?? '';
$stmt = db()->prepare(
"SELECT * FROM products WHERE name LIKE ? LIMIT 10"
);
$stmt->execute(["%$q%"]);
echo json_encode($stmt->fetchAll());
FRONTEND
const search = document.querySelector('#search');
search.addEventListener('input', async () => {
const res = await fetch('/api/search.php?q=' + search.value);
const products = await res.json();
renderProducts(products);
});
18. API JSON
public/api/products.php
<?php
header('Content-Type: application/json');
echo json_encode(Product::latest());
19. ADMIN LOGIN 2026
CSS
.login-box {
backdrop-filter: blur(24px);
border:1px solid rgba(255,255,255,.2);
box-shadow:
0 20px 60px rgba(255,79,154,.2);
border-radius:24px;
}
20. RESPONSIVE MOBILE UI
Bottom navigation
<nav class="bottom-nav">
<a href="/">Home</a>
<a href="/cart">Cart</a>
<a href="/profile">Profile</a>
</nav>
CSS
.bottom-nav {
position:fixed;
bottom:0;
left:0;
right:0;
height:64px;
display:flex;
justify-content:space-around;
background:#fff;
}
21. TIKTOK SHOP STYLE
Sticky buy button
.buy-bar {
position:fixed;
bottom:64px;
left:0;
right:0;
}
22. ONE PAGE CHECKOUT
Layout
[cart summary]
[address]
[payment]
[voucher]
[submit]
23. VIETQR THANH TOÁN
QR image
<img src="https://img.vietqr.io/image/MB-123456789-print.png?amount=300000">
24. AUTO PAYMENT CHECK
Có thể dùng:
Momo API
VietQR API
PayOS
ZaloPay
25. VOUCHER SYSTEM
SQL
CREATE TABLE vouchers (
id INT AUTO_INCREMENT PRIMARY KEY,
code VARCHAR(50) UNIQUE,
type ENUM('percent','fixed') DEFAULT 'percent',
value INT DEFAULT 0,
min_order INT DEFAULT 0,
max_discount INT DEFAULT 0,
expired_at DATETIME,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
26. APPLY VOUCHER
if ($voucher['type'] === 'percent') {
$discount = ($total * $voucher['value']) / 100;
}
27. TRACKING VẬN ĐƠN
SQL
ALTER TABLE orders
ADD tracking_code VARCHAR(100),
ADD shipping_provider VARCHAR(100);
28. SHIPPING APIs
Tích hợp:
GHN
GHTK
Viettel Post
Ninja Van
29. ADMIN DASHBOARD
Stats SQL
SELECT COUNT(*) FROM orders;
SELECT SUM(total) FROM orders;
30. CHART.JS
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
31. EXPORT EXCEL
Install
composer require phpoffice/phpspreadsheet
Export
$sheet->setCellValue('A1', 'Mã đơn');
32. SEO META
<meta name="description" content="Shop Online">
<meta property="og:title" content="Shop Online">
<meta property="og:image" content="...">
33. PRODUCT SCHEMA
<script type="application/ld+json">
{
"@context":"https://schema.org",
"@type":"Product",
"name":"Tên sản phẩm",
"offers":{
"@type":"Offer",
"price":"300000",
"priceCurrency":"VND"
}
}
</script>
34. MESSENGER CHAT FLOAT
<a
href="https://m.me/yourpage"
class="messenger-float"
>
Messenger
</a>
35. SKELETON LOADING
.skeleton {
animation:pulse 1.5s infinite;
}
36. CACHE SYSTEM
Redis
composer require predis/predis
37. SECURITY
CSRF
$_SESSION['csrf'] = bin2hex(random_bytes(32));
Rate limit
if ($attempts > 5) {
die('Too many attempts');
}
Secure session
session_set_cookie_params([
'httponly' => true,
'secure' => true,
'samesite' => 'Lax'
]);
38. IMAGE OPTIMIZATION
Responsive image
<picture>
<source srcset="image.webp" type="image/webp">
<img src="image.jpg">
</picture>
39. INFINITE SCROLL
window.addEventListener('scroll', () => {
if(window.innerHeight + window.scrollY >= document.body.offsetHeight - 500) {
loadMore();
}
});
40. NOTIFICATION TOAST
Toastify({
text: 'Đã thêm giỏ hàng'
}).showToast();
41. RECOMMENDED LIBRARIES
Frontend
Swiper.js
AOS animation
Toastify
Alpine.js
Backend
PHPMailer
PhpSpreadsheet
Predis
Intervention Image
42. SERVER RECOMMEND
Shared hosting
PHP 8.3
LiteSpeed
Redis
VPS
NGINX
MariaDB
Redis
Supervisor
43. FINAL 2026 STACK
PHP 8.3
MVC
PWA
Redis cache
Cloudflare CDN
WebP images
Dark mode
AJAX realtime
Responsive mobile
One page checkout
QR payment
Voucher system
SEO schema
Messenger chat
Admin dashboard
Excel export
44. KẾT QUẢ CUỐI CÙNG
Sau khi nâng cấp đầy đủ:
giống app mobile thật
tốc độ rất nhanh
SEO tốt hơn WordPress
UI giống TikTok Shop
tối ưu chuyển đổi
chạy tốt mobile
có thể scale lớn
dễ chạy quảng cáo
dễ làm landing page
production ready