Thứ Tư, 6 tháng 5, 2026

Warning: header already sent – lỗi "khó chịu" nhất nhì PHP

Nhiều khi chúng ta làm những việc hết sức đơn giản, và trong thâm tâm, mặc nhiên chúng ta đã được "lập trình" rằng việc đó dĩ nhiên là bình thường!


Trong lập trinh cũng vậy, ví dụ bạn viết một đoạn code rất bình thường, hay bạn luôn mặc định đoạn code đó là "bình thường":


<?php



header("Location: index.php");



?>


Ý tưởng: redirect sang trang khác, ví dụ Home, About Us...Nói chung là...bình thường! Bạn bấm chạy…


Và…


Warning: Cannot modify header information - headers already sent


Bạn nhìn màn hình…


"Header gì? Gửi lúc nào??? Không hiểu??"


Chúc mừng, bạn vừa gặp một trong những lỗi "bình thường" của PHP 


Lỗi "header already sent" trong PHP xảy ra khi bạn gửi output (echo, HTML, khoảng trắng…) trước khi gọi hàm header().




Hiểu đơn giản 


PHP có một "luật ngầm":

Phải gửi header trước, rồi mới gửi nội dung


Nhưng bạn lại làm:

  • gửi nội dung trước
  • rồi mới gửi header


"Giám sát viên" PHP lạnh lùng phán: "Không được! Header phải đầu tiên!" 



Ví dụ thực tế


Bạn gửi bưu kiện, thông thường mọi người sẽ:

  • Ghi địa chỉ (header)
  • Gửi hàng (data)


Nhưng bạn lại:

  • gửi hàng trước
  • rồi mới ghi địa chỉ


Bưu điện...ngơ ngác: "Ơ kìa???" 


PHP cũng vậy 



Lỗi kinh điển


Case 1: echo trước header


<?php



echo "Hello";

header("Location: index.php");



?>


Bạn đã "in ra" màn hình Hello rồi

Vì vậy header không gửi được nữa


Case 2: có khoảng trắng trước <?php


   <?php

header("Location: index.php");


3 dấu cách đó… cũng tính là output 


Đây là lỗi:

"nhìn không thấy nhưng phá banh chương trình" 


Case 3: HTML trước PHP


<h1>Hello</h1>



<?php



header("Location: index.php");



?>


HTML = output

Dẫn tới header fail


Case 4: file include gây lỗi


include "config.php";

header("Location: home.php");


Nếu config.php có:

  • echo
  • hoặc khoảng trắng


Kết quả cũng lỗi vì "liên quan"



Cách fix 


Cách 1: Đặt header trước mọi thứ


<?php



header("Location: index.php");



exit;



?>


Không echo trước đó


Cách 2: Không có khoảng trắng


File phải bắt đầu như này:


<?php


Không có:

  • space
  • dòng trống
  • BOM


Cách 3: Dùng output buffering (hơi xịn một chút)


<?php



ob_start();

echo "Hello";

header("Location: index.php");

ob_end_flush();



?>


PHP sẽ "giữ lại" output

Kết quả là cho phép header chạy trước, kiểu như header có vé VIP.


Nhưng:

Lính mới nên hạn chế dùng cách này 



Test thử (rất nên làm, làm rồi sẽ hiểu)


Tạo file:

<?php



echo "Test";



header("Location: https://google.com");



?>


Mở lên sẽ nhận món quà...lỗi


Sửa lại:

<?php



header("Location: https://google.com");

exit;



?>


Kết quả là redirect OK 




Debug kiểu dev "xịn sò"


Khi gặp lỗi này:

  • Xem có echo không
  • Xem có HTML trước PHP không
  • Xem có khoảng trắng không
  • Check file include


90% lỗi nằm ở đây



Một sự thật hơi "đau"


Lỗi này:

  • không khó
  • nhưng rất "khó chịu"


Vì:

Bạn nhìn code… thấy đúng hết, chẳng có gì phải "lăn tăn"


Nhưng thực tế:

sai 1 dấu cách 



Tổng kết


"header already sent" không phải lỗi phức tạp


Nó chỉ là: bạn đã gửi output trước


Nhớ:

  • header phải đứng đầu
  • không echo trước
  • không có khoảng trắng



FAQ nhanh


Có thể echo rồi redirect không?

Không (trừ khi dùng ob_start)


Tại sao lỗi vẫn xảy ra dù không thấy echo?

Có thể do khoảng trắng hoặc file include


exit có cần không?

Có, để dừng script sau khi redirect



Bạn có thể cũng đang gặp:

PHP không nhận dữ liệu từ form

Undefined index

MySQL không connect