Vài vấn đề về xử lý hàm header() trong PHP

Lỗi Headers Already Sent  là 1 lỗi thường gặp đến khó tin, và mình đã nhận được rất rất nhiều câu hỏi về nó dạng như “Nó là cái gì ?, Sao lại như thế?” , vì vậy mình quyết định đưa nó lên bàn mổ nhằm làm sáng tỏ vấn đề

Một HTTP response ( trả về ) thông thường bao gồm 2 phần là header( đầu) và content (nội dung). Phần header trong 1 HTTP response chỉ ra bản chất của response và  cách xử lý với chúng. VD: 1 response có chỉ ra “Location” trong header , cái này báo cho trình duyệt để tự động chuyển đến Url được chỉ ra trong header.Hoặc 1 response có “Content-type” trong header, trình duyệt sẽ xử lý nội dung theo loại nội dung: image xử lý khác, text xử lý khác, Flash xử lý khác …
Header cũng được sử dụng khi bạn làm việc với session, có thể bạn ko thấy rõ được điều này, nhưng trong những hàm về session của PHP nó đều dùng thông qua cookie. Vì thế ngay khi bạn dùng session bạn đã tạo ra 1 HTTP header. Hàm session_start() khởi tạo 1 tập cookie và vì thế nó gửi 1 HTTP header xuống trình duyệt.
Phần còn lại của HTTP response là nội dung (content), cái này chắc bạn nhìn thấy nó dễ dàng rồi. Phần này phải được gửi đi sau header, và một khi nội dung đã được gửi đi thì sẽ ko có header nào có thể được gửi xuống trình duyệt nữa. Nội dung bao gồm các đoạn mã HTML hoặc bất cứ thứ gì được tạo ra trong script của bạn. Khi bạn gọi echo() bạn đã xuất nội dung xuống trình duyệt rồi đấy.

Thế thì liên quan gì đến lỗi “Headers Already Sent”? Lỗi này xuất hiện khi bạn cố gắng gửi 1 HTTP header xuống trình duyệt sau khi nội dung đã được gửi xuống. Trong một HTTP response đều này là phạm pháp , ko được phép bởi vì nó đã làm rồi, trình duyệt đã xử lý xong phần nội dung được gửi xuống rồi, header ko còn tác dụng gì nữa cả .

Và như tớ đã nói ở trên, session_start() gửi header xuống client, hàm header() cũng gửi header xuống … vì thế 2 thằng này là dễ gặp lỗi “Headers Already Sent” nhất nếu như đã gửi nội dung xuống trình duyệt trước khi gọi chúng.

Giải pháp cho vấn đề này đơn giản chỉ là : hãy chắc chắn rằng bạn không gửi bất cứ nội dung gì xuống trình duyệt trước khi gọi các hàm có làm việc với header. Nói thì như thế nhưng thực tế cũng khá khó khăn vì chúng ta là người Việt, chúng ta phải viết tiếng Việt trong lập trình, chúng ta phải dùng Unicode… và đa số các Editor PHP , khi bạn chọn encoding cho file là Utf-8 nó sẽ vô tư kèm theo cho bạn 3 kí tự ở đầu file gọi là BOM (byte order mark), các kí tự này thuộc dạng vô hình nên chúng ta sẽ ko nhìn thấy chúng , nhưng máy tính thì thấy vì thế cho nên bạn có bỏ ra cả tháng trời để ngồi mò mẫm trong đoạn code xem có kí tự nào được xuất ra hay chưa thì cũng vô vọng. Cách đơn giản nhất để xử lí vấn đề này là hãy chọn Utf-8 witthout BOM trong Editor của bạn .

Nhưng có một giải pháp khác an toàn nhàn nhã hơn là hãy giao tất cả những gì bạn xuất ra cho bộ đệm (output buffering ) nắm giữ, sau khi xử lý xong tất cả sẽ được cho vào đại pháo bắn 1 lần xuống trình duyệt không cần lo sau trước thứ tự gì nữa cả . Hãy thêm vào đầu code của bạn ob_start() và cuối code ob_end_flush(), bạn có thể vừa lập trình vừa ngủ , để biết thêm về những hàm output buffering  hãy tìm đến PHP Manual

Chúc bạn thành công,

FOLLOW US

Leave a Reply

Your email address will not be published. Required fields are marked *