PHP chạy trên máy chủ: nó dựng trang, gửi HTML hoàn chỉnh rồi dừng. JavaScript chạy trong trình duyệt của người xem, nơi nó phản hồi các cú nhấp chuột và thay đổi trang sau khi trang đã tải xong; với Node.js, JavaScript cũng chạy được trên máy chủ. Vì vậy hai ngôn ngữ này giống cộng sự hơn là đối thủ: một trang web điển hình dùng PHP (hoặc Node.js) trên máy chủ và JavaScript trong trình duyệt.
Đoạn code PHP này chạy trên máy chủ. Trình duyệt chỉ nhận những gì nó in ra, và tab Trang hiển thị kết quả đó:
Hãy xem tab Đầu ra: không còn chút PHP nào, chỉ có HTML. Cùng danh sách đó mà dựng bằng JavaScript trong trình duyệt thì trông như sau:
const products = [
{ name: "Keyboard", price: 49 },
{ name: "Mouse", price: 19 },
{ name: "Monitor", price: 189 },
];
const ul = document.querySelector("#cart"); // an empty <ul id="cart"> in the HTML
for (const p of products) {
const li = document.createElement("li");
li.textContent = `${p.name}: $${p.price}`;
ul.append(li);
}
Phiên bản PHP gửi về một trang đầy đủ, công cụ tìm kiếm và điện thoại chậm đọc được ngay. Phiên bản JavaScript có thể cập nhật danh sách sau đó mà không cần tải lại trang, chẳng hạn khi người xem xóa một món hàng.
Mỗi ngôn ngữ chạy ở đâu
| PHP | JavaScript | |
|---|---|---|
| Chạy trên | máy chủ web (hoặc terminal) | trình duyệt, và máy chủ với Node.js, Deno hoặc Bun |
| Truy cập được | tệp, cơ sở dữ liệu, biến môi trường, thông tin bí mật | trang (DOM), cú nhấp chuột, bộ nhớ lưu trữ của trình duyệt |
| Vòng đời | chạy một lần cho mỗi request | suốt thời gian trang mở (trình duyệt), hoặc một tiến trình chạy lâu dài (Node.js) |
| Việc thường làm | dựng trang, xử lý form, API, làm việc với cơ sở dữ liệu | tương tác, cập nhật trực tiếp, ứng dụng một trang, máy chủ Node.js |
| Người xem đọc được code | không | có, ngay trong trình duyệt |
Hàng cuối quan trọng về bảo mật: mọi thứ trong JavaScript phía trình duyệt đều hiện ra với người xem, nên mật khẩu, API key và bước kiểm tra giá phải nằm trên máy chủ.
So sánh cú pháp
Hai ngôn ngữ trông giống nhau vì cùng vay mượn từ C: dấu ngoặc nhọn, if, for, while, function, return. Khác biệt nằm ở chi tiết:
| Việc cần làm | PHP | JavaScript |
|---|---|---|
| Biến | $name = "Ada"; | let name = "Ada"; |
| Hằng số | const MAX = 10; | const MAX = 10; |
| Nối chuỗi | "Hi " . $name | "Hi " + name |
| Chuỗi mẫu | "Hi $name" | `Hi ${name}` |
| Danh sách | ["a", "b"] | ["a", "b"] |
| Khóa/giá trị | ["id" => 1] | { id: 1 } |
| Độ dài | count($list), strlen($s) | list.length, s.length |
| Vòng lặp | foreach ($list as $item) | for (const item of list) |
| Arrow function | fn($x) => $x * 2 | (x) => x * 2 |
| In ra | echo "Hi"; | console.log("Hi"); |
Đây là một hàm dùng callback trong PHP:
Và trong JavaScript, nơi map và filter là phương thức của mảng:
const prices = [12.5, 8, 30, 4.25];
const withTax = prices.map((p) => Math.round(p * 1.2 * 100) / 100);
const cheap = withTax.filter((p) => p < 15);
console.log(withTax.join(", "));
console.log("Under 15: " + cheap.join(", "));
Toán tử +: cái bẫy kinh điển
Trong JavaScript, + vừa cộng số vừa nối chuỗi, nên chỉ cần có một chuỗi ở đâu đó là phép cộng biến thành phép nối. PHP tách riêng hai việc: + luôn cộng và . luôn nối.
console.log("10" + 5); // "105"
console.log("10" - 5); // 5
console.log("3" * "4"); // 12
console.log(0.1 + 0.2 === 0.3); // false
Cả hai ngôn ngữ cũng có == so sánh lỏng và === so sánh chặt. Lời khuyên ở cả hai là như nhau: dùng ===, trừ khi bạn thật sự muốn so sánh giữa các kiểu khác nhau.
Truyền dữ liệu từ PHP sang JavaScript
PHP chạy trước, nên nó có thể ghi dữ liệu thẳng vào trang để JavaScript trong trình duyệt dùng. json_encode biến một mảng PHP thành JavaScript hợp lệ:
Tab Đầu ra hiển thị script được tạo ra với dữ liệu đã điền sẵn. Cờ JSON_HEX_TAG escape < và >, nên một giá trị chứa </script> không thể kết thúc script sớm. Xem thêm các tùy chọn trong json_encode.
Chiều ngược lại đi qua HTTP: JavaScript trong trình duyệt gọi fetch("/api/cart.php"), script PHP chạy và trả lời bằng JSON:
<?php
// api/cart.php
header('Content-Type: application/json');
echo json_encode(['items' => 3, 'total' => 257]);
const res = await fetch("/api/cart.php");
const cart = await res.json();
console.log(cart.total); // 257
PHP vs Node.js trên máy chủ
Khi JavaScript chạy trên máy chủ qua Node.js, việc so sánh trở thành một lựa chọn thực sự.
| PHP | Node.js | |
|---|---|---|
| Mô hình | mỗi request một lần chạy mới, không chia sẻ gì | một tiến trình chạy lâu dài với event loop |
| Khi chờ I/O | chặn request đó (các request khác chạy ở worker khác) | không chặn, async/await |
| Mạnh ở | trang web render trên máy chủ, CMS, ứng dụng CRUD cổ điển | ứng dụng thời gian thực, websocket, nhiều kết nối nhàn rỗi |
| Hosting | bất kỳ shared host nào, PHP-FPM | trình quản lý tiến trình Node hoặc nền tảng như Vercel |
| Framework lớn | Laravel, Symfony, WordPress | Express, NestJS, Next.js |
| Một ngôn ngữ cho cả frontend và backend | không | có |
Mô hình của PHP dễ tha thứ: một bug hay rò rỉ bộ nhớ chỉ ảnh hưởng một request, và mỗi request đều bắt đầu sạch sẽ. Mô hình của Node có thể giữ trạng thái và để kết nối luôn mở, rất hợp với chat và dashboard trực tiếp, nhưng một lần crash hay một vòng lặp chặn sẽ ảnh hưởng mọi người dùng của tiến trình đó.
Nên học ngôn ngữ nào
Bạn sẽ cần JavaScript cho bất kỳ trang web tương tác nào, vì đó là ngôn ngữ duy nhất trình duyệt chạy. Câu hỏi là thứ gì chạy trên máy chủ:
- Học PHP tiếp theo nếu bạn muốn làm việc với WordPress, Laravel hay vô số trang PHP đang có, hoặc muốn cách đơn giản nhất để đưa một trang web động lên hosting giá rẻ. Bắt đầu với PHP là gì.
- Ở lại với JavaScript (Node.js) nếu bạn muốn một ngôn ngữ cho toàn bộ stack hoặc đang xây tính năng thời gian thực.
Lộ trình phổ biến là HTML và CSS, rồi JavaScript trong trình duyệt, rồi một ngôn ngữ phía máy chủ. Dù chọn ngôn ngữ máy chủ nào, form, session, cơ sở dữ liệu và API JSON đều dựa trên cùng những ý tưởng HTTP, nên kiến thức của bạn vẫn dùng được.
Câu hỏi thường gặp
JavaScript có thay thế được PHP không?
Trên máy chủ thì có: Node.js (cùng Express, Next.js hoặc framework tương tự) làm được đúng những việc PHP làm. Trong trình duyệt, PHP hoàn toàn không thay được JavaScript, vì trình duyệt chỉ chạy JavaScript. Đó là lý do nhiều trang web dùng PHP hoặc Node trên máy chủ và JavaScript trong trình duyệt.
Làm sao truyền một biến PHP sang JavaScript?
In nó vào trang dưới dạng JSON: <script>const user = <?= json_encode($user, JSON_HEX_TAG) ?>;</script>. json_encode tạo ra JavaScript hợp lệ cho chuỗi, số, mảng và đối tượng, còn JSON_HEX_TAG ngăn một </script> nằm trong dữ liệu đóng thẻ lại.
JavaScript có gọi được hàm PHP không?
Không gọi trực tiếp được, vì PHP chạy trên máy chủ còn JavaScript chạy trong trình duyệt. JavaScript gửi một request HTTP bằng fetch('/api.php?id=3'), script PHP chạy và in ra response (thường là JSON), rồi JavaScript đọc kết quả đó.
PHP có nhanh hơn Node.js không?
Còn tùy loại tải. Node.js xử lý tốt nhiều kết nối chậm cùng lúc (chat, websocket) nhờ event loop. PHP 8 với OPcache chạy nhanh cho các trang request và response thông thường. Với hầu hết trang web, điểm nghẽn là cơ sở dữ liệu chứ không phải ngôn ngữ.