banner

[Rule] Rules  [Home] Main Forum  [Portal] Portal  
[Members] Member Listing  [Statistics] Statistics  [Search] Search  [Reading Room] Reading Room 
[Register] Register  
[Login] Loginhttp  | https  ]
 
Forum Index Thảo luận hệ điều hành *nix BOM Signature - vấn đề sinh lỗi trong PHP - Phương pháp giải quyết  XML
  [Question]   BOM Signature - vấn đề sinh lỗi trong PHP - Phương pháp giải quyết 15/09/2008 03:35:49 (+0700) | #1 | 151255
[Avatar]
xnohat
Moderator

Joined: 30/01/2005 13:59:19
Messages: 1210
Location: /dev/null
Offline
[Profile] [PM] [Email] [WWW] [Yahoo!] [MSN]
Trong quá trình nghiên cứu về PHP lúc trước tôi gặp nhiều bạn đã gặp phải tình huống rắc rối khi lập trình PHP
Các bạn lập trình đúng cú pháp, đúng quy tắc, nhưng trong mã nguồn có sử dụng các hàm liên quan tới header như hàm Header(), Cookie() .v.v. thì thường gặp phải lỗi

Code:
Warning:Cannot modify header information....


Lỗi này xảy ra là do đoạn script cố gắng gửi một header tới trình duyệt khi mà trình duyệt đã hiện dữ liệu lên màn hình ( hàm echo, print đã hoạt động ). Về cơ chế, thì mã HTML chuẩn sẽ có phần tag <head></head> nằm trước tag <body></body> để "cấu hình" gì đó cho trình duyệt, vậy nên khi PHP script thực hiện echo dữ liệu thì nó sẽ sinh ra một tài liệu HTML chuẩn có cấu trúc như trên, vậy nếu sau đó ta gửi đi một hàm header() tức là tạo một header mới cho tài liệu HTML là vô lý vì tài liệu HTML đã được tạo xong.

Các bạn bị lỗi này sẽ tìm rất kĩ và đã cố gắng xem về mặt logic mình có sai gì không, có gửi dữ liệu gì về trước khi gọi hàm header không, nếu có thì dùng phương pháp cache dữ liệu vào buffer bằng cặp hàm ob_start() và ob_flush()

Tham khảo ở bài viết này:
/hvaonline/posts/list/24937.html

Sau khi đã tìm kĩ rồi mà không tìm ra được nguyên nhân lỗi không rơi vào các trường hợp như trên thì bạn nên để ý tới trường hợp sau:

Bạn Save file .php bằng một chương trình có hỗ trợ lưu file dưới dạng Unicode UTF-8 encoding ( bạn phải lưu ở encoding này nếu bạn muốn hiển thị tiếng việt bạn ghi trong file đó ). Chương trình bạn dùng có một tùy chọn là add BOM signature.
Vậy BOM sign là gì mà tại sao nó gây lỗi?
BOM sign (BOM viết tắt của Byte Order Mark) là một dạng "đánh dấu" để một chương trình nào đó biết được đây là file được encoding với UTF-x format ( đa phần là chương trình "cổ" ) gồm 3 kí tự ASCII có mã hex là \xEF\xBB\xBF thường đặt ở đầu file, những chương trình ko hỗ trợ UNICODE sẽ hiện kí tự này ra và PHP là một điển hình. Do đó khi lưu bạn nên bỏ tùy chọn này để tránh gây lỗi

Vậy lỗi xảy ra như thế nào ?
Như ta đã biết trước khi gọi hàm header() thì không một dữ liêu nào được echo lên trình duyệt nếu ko sẽ sinh lỗi như ở đầu bài viết đã đề cập, mà PHP mặc định sẽ echo những dữ liệu nằm bên ngoài cặp tag <?php ?> lên trình duyệt, vậy nên nếu trước tag <?php có một dòng trống, khoảng trắng hay là dấu hiệu BOM thì nó sẽ được PHP echo lên màn hình tức là đã send dữ liệu về trình duyệt ---> lỗi tè le luôn khi bạn gọi hàm header()

vậy sửa sao đây, sửa thì đương nhiên là xóa quách mấy cái gây rắc rối đó đi, xóa dòng trống khoảng trắng thì dễ òi smilie nhưng cái BOM thì sao ????, chà một khi BOM đã được Add thì ít có chương trình nào remove nó ra vây nên vấn đề rất thảm smilie, các chương trình hỗ trợ UNICODE thì sẽ không hiện các kí tự đó lên đâu ( các editor support UNICODE đều sẽ không hiện ), vậy thì làm sao ?, ta đã biết là BOM gồm 3 kí tự có mã hex là \xEF\xBB\xBF ở đầu file vậy thì cứ kiếm nó mà xóa smilie , nhưng không thấy thì sao xóa giờ smilie , èo vậy thì phải dùng chính thằng PHP để xóa vì bản thân nó ko support UNICODE, dùng hàm str_replace() để kiếm 3 cái kí tự kỉ gió BOM và thay nó bằng null ( tức là "" ) là xong smilie . Để tiện NoHat đã viết một đoạn script nhỏ bằng PHP để bạn có thể remove cái khỉ gió BOM này đi cho rảnh nợ

Code:
<?php
/* Remove BOM signature (Byte Order Mark) tool
Written by XNohat (xnohat@gmail.com)
*/
$filermBOM = "abc.php"; //file need remove BOM sign
$handleFrmBOM = fopen($filermBOM,"r+");
$contents = fread($handleFrmBOM, filesize($filermBOM));
fclose($handleFrmBOM);
if(strstr($contents,"\xEF\xBB\xBF") == FALSE) die("No BOM signature on this file $filermBOM");
$fixedcontents=str_replace("\xEF\xBB\xBF","",$contents);
$handleFrmBOM = fopen($filermBOM,"w");
if(fwrite($handleFrmBOM,$fixedcontents) == FALSE)
{
	echo"Cannot write Removed BOM sign data to file";
}else{
	fclose($handleFrmBOM);
	echo "Removed BOM signature from this file";
     }
?>


Nếu thích thì bạn cứ chỉnh sửa lại chút là đoạn script này có thể chạy từ dòng lệnh để remove BOM hàng loạt file.

Bài viết này chỉ dành cho một số bạn mới nghiên cứu PHP, ai thạo rồi mình xin khất smilie, đừng réo tớ mà chửi tội làm rác Forum smilie

iJust clear, "What I need to do and how to do it"/i
br
brBox tán gẫu dời về: http://www.facebook.com/hvaonline
[Up] [Print Copy]
[digg] [delicious] [google] [yahoo] [technorati] [reddit] [stumbleupon]
Go to: 
 Users currently in here 
1 Anonymous

Powered by JForum - Extended by HVAOnline
 hvaonline.net  |  hvaforum.net  |  hvazone.net  |  hvanews.net  |  vnhacker.org
1999 - 2013 © v2012|0504|218|