Sửa lỗi PHP Parse error: syntax error, unexpected token khi chạy PHP Scripts

beginner🐘 PHP2026-05-17| PHP 8.0+, Linux/Windows/macOS, Apache/Nginx, CLI

Error Message

Parse error: syntax error, unexpected token "echo", expecting "," or ";" in /var/www/html/index.php on line 15
#php#syntax-error#parse-error#debug

Chuyện Gì Đang Xảy Ra

Trước khi PHP chạy bất kỳ dòng nào, nó đọc toàn bộ script từ đầu đến cuối và kiểm tra cú pháp. Gặp dấu chấm phẩy bị thiếu, dấu ngoặc chưa đóng, hay ký tự lạ — nó dừng lại ngay tại đó và ném ra lỗi Parse error. Script không bao giờ được thực thi.

Lỗi trông như thế này:

Parse error: syntax error, unexpected token "echo", expecting "," or ";" in /var/www/html/index.php on line 15

PHP đang nói: "Tôi đang chờ dấu phẩy hoặc dấu chấm phẩy để kết thúc câu lệnh trước, nhưng lại thấy echo." Điều quan trọng cần hiểu: vấn đề thực sự hầu như không bao giờ nằm ở dòng được báo cáo. Thường là dòng phía trên nó — nơi bạn bỏ sót phần chưa đóng.

Quy Trình Debug

1. Kiểm tra dòng phía trước dòng được báo cáo

Đi đến dòng 14 — một dòng trên dòng 15 được báo cáo. Chín lần trong mười, có một dấu chấm phẩy bị thiếu ngay tại đó.

<?php
// Dòng 14 — không có dấu chấm phẩy ở cuối
$message = "Hello, world"
echo $message;  // Dòng 15 — PHP vấp ở đây

Thêm dấu chấm phẩy vào là xong:

$message = "Hello, world";
echo $message;

2. Chạy kiểm tra cú pháp PHP từ terminal

Bỏ việc đoán mò. Dùng php -l (lint) để lấy lỗi chính xác mà không cần thực sự chạy script:

php -l /var/www/html/index.php

File không có lỗi:

No syntax errors detected in /var/www/html/index.php

File có lỗi:

Parse error: syntax error, unexpected token "echo", expecting "," or ";" in /var/www/html/index.php on line 15

Hãy đưa bước này vào quy trình làm việc — chạy trước mỗi lần test trên trình duyệt.

3. Bật hiển thị lỗi trong quá trình phát triển

Thấy trang trắng trống? PHP đang ẩn lỗi đi. Thêm ba dòng này vào đầu script của bạn tạm thời:

<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

Muốn sửa trong php.ini thay thế:

display_errors = On
error_reporting = E_ALL

Sau khi chỉnh php.ini, khởi động lại server:

sudo systemctl restart php8.2-fpm
# hoặc
sudo systemctl restart apache2

Nguyên Nhân Thường Gặp Và Cách Sửa

Thiếu dấu chấm phẩy

Nguyên nhân của phần lớn các lỗi này. Mọi câu lệnh PHP đều kết thúc bằng ; — không có ngoại lệ.

// Sai
$name = "Alice"
echo $name;

// Đúng
$name = "Alice";
echo $name;

Dấu nháy không khớp hoặc chưa đóng

Mở một dấu nháy rồi quên đóng, PHP sẽ tiếp tục đọc cho đến khi tìm thấy dấu nháy khớp — nuốt mọi thứ ở giữa, kể cả dòng mới.

// Sai — mở dấu nháy đơn, không bao giờ đóng
$sql = 'SELECT * FROM users WHERE id = 1;
echo $sql;

// Đúng
$sql = 'SELECT * FROM users WHERE id = 1';
echo $sql;

Dấu ngoặc đơn hoặc dấu ngoặc nhọn chưa đóng

// Sai — thiếu dấu ngoặc đơn đóng
if ($x > 0 {
    echo "positive";
}

// Đúng
if ($x > 0) {
    echo "positive";
}

Lỗi cú pháp Heredoc

Heredoc có quy tắc định dạng nghiêm ngặt. Trên PHP cũ hơn 7.3, định danh đóng phải nằm ở cột 0 — không có khoảng trắng phía trước, không có khoảng trắng phía sau, chỉ là nhãn và dấu chấm phẩy.

// Sai trên PHP < 7.3 — thẻ đóng bị thụt vào
$text = <<<EOT
    Some text
    EOT;

// Đúng cho mọi phiên bản PHP — thẻ đóng ở cột 0
$text = <<<EOT
    Some text
EOT;

// PHP 7.3+ cũng chấp nhận thụt vào đồng nhất ở thẻ đóng
$text = <<<EOT
    Some text
    EOT;

Cú pháp PHP 8 trên server PHP 7

Named arguments, biểu thức match, và toán tử nullsafe (?->) đều yêu cầu PHP 8.0+. Chạy đoạn code đó trên PHP 7 sẽ gây ra parse error ngay lập tức.

# Kiểm tra phiên bản đang thực sự chạy
php --version

# Named arguments — chỉ PHP 8.0+ trở lên
array_slice(array: $arr, offset: 0, length: 3);  // Lỗi trên PHP 7.x

Hãy nâng cấp lên PHP 8 hoặc viết lại code bị ảnh hưởng để dùng positional arguments.

BOM hoặc ký tự vô hình

Các file được dán từ tài liệu Word hoặc lưu với encoding UTF-8 BOM thường mang theo các byte vô hình trước <?php. PHP nhìn thấy chúng, bị nhầm lẫn, và chết trước khi đến được code của bạn.

# Kiểm tra BOM
file /var/www/html/index.php

# Xóa bằng sed
sed -i '1s/^\xEF\xBB\xBF//' /var/www/html/index.php

Xác Nhận Đã Sửa Xong

Sau khi thực hiện thay đổi, hãy lint trước — rồi mới test trên trình duyệt. Đừng bỏ qua bước lint.

php -l /var/www/html/index.php

Sau đó chạy script trực tiếp hoặc truy cập qua HTTP:

php /var/www/html/index.php
# hoặc
curl -I http://localhost/index.php

Đang dùng Nginx + PHP-FPM? Cũng nên kiểm tra log lỗi của FPM — nó thường hiển thị các lỗi không xuất hiện trên trình duyệt:

sudo tail -f /var/log/php8.2-fpm.log

Bài Học Rút Ra

  • Dòng được báo cáo hiếm khi là dòng bị lỗi. Nhìn lên một hoặc hai dòng phía trên nó. Biểu thức chưa đóng bắt đầu từ đó, không phải nơi PHP phàn nàn.
  • Chạy php -l thường xuyên. Tích hợp vào hành động lưu file trong editor hoặc pre-commit hook. Lỗi cú pháp không có lý do gì để đến được server.
  • Tắt display_errors trên môi trường production. Parse error làm lộ đường dẫn file và cấu trúc code nội bộ. Ghi log phía server; đừng bao giờ in ra cho người dùng thấy.
  • Cài đặt linter thời gian thực. PHP Intelephense cho VS Code hoặc trình kiểm tra tích hợp của PhpStorm phát hiện lỗi cú pháp ngay khi bạn gõ — không cần chờ đến runtime mới biết mình quên dấu chấm phẩy.

Related Error Notes