我刚开始涉足php,恐怕我需要一些帮助来弄清楚如何操纵utf-8字符串。Php无法找到拆分utf-8字符串的方法
我正在ubuntu 11.10 x86,php版本5.3.6-13ubuntu3.2中工作。我有一个UTF-8编码的文件(VIM :set encoding
证实了这一点),然后我用mb_detect_encoding($line)
报告UTF-8
$file = fopen("file.txt", "r");
while(!feof($file)){
$line = fgets($file);
//...
}
fclose($file);
- 继续读它,如果我做
echo $line
我可以看到正确的线(无在浏览器- 所以我想一切都很好,浏览器和Apache。虽然我没有搜索我的Apache配置为AddDefaultCharset,并试图将HTTP元标记的字符编码(以防万一)
当我尝试拆分使用$arr = mb_split(';',$line)
字符串结果数组字段包含错位utf-8字符(mb_detect_encoding($arr[0])
也报告utf-8)。
所以echo $arr[0]
会导致类似这样的事情:ΑΘΗÎÎ
。
我试过设置mb_detect_order('utf-8')
,mb_internal_encoding('utf-8')
,但没有任何改变。我还尝试使用this w3 perl regex手动检测utf-8,因为我在某处读取mb_detect_encoding有时可能失败(神话?),但结果也一样。
所以我的问题是我该如何正确拆分字符串?正在走下mb_
路径错误的路?我错过了什么?
谢谢你的帮助!
更新:我加入样品字符串和BASE64当量(感谢@克里斯他建议)
1. original string: "ΑΘΗΝΑ;ΑΙΓΑΛΕΩ;12242;37.99452;23.6889"
2. base64 encoded: "zpHOmM6Xzp3OkTvOkc6ZzpPOkc6bzpXOqTsxMjI0MjszNy45OTQ1MjsyMy42ODg5"
3. first part (the equivalent of "ΑΘΗΝΑ") base64 encoded before splitting: "zpHOmM6Xzp3OkQ=="
4. first part ($arr[0] after splitting): "ΑΘΗÎΑ"
5. first part after splitting base64 encoded: "77u/zpHOmM6Xzp3OkQ=="
好了,这样做后,似乎有3之间的77u/
差异。和5.哪个according to this是utf-8 BOM标记。那我该如何避免呢?
更新2:我醒来后,今天精神焕发,心中有提示,我再次尝试。看起来$line=fgets($file)
正确读取第一行(没有损坏的字符),并且每个后续行都失败。那么我base64_encoded
的第一行和第二行,以及77u/
bom出现在base64'd字符串的第一行只有。然后我在vim中打开了违规文件,并输入:set nobomb
:w
来保存没有bom的文件。再次启动PHP表明第一行也被破坏了。根据@ hakre的remove_utf8_bom
我增加它的功能互补
function add_utf8_bom($str){
$bom= "\xEF\xBB\xBF";
return substr($str,0,3)===$bom?$str:$bom.$str;
}
和瞧每一行正确读取。
我不太喜欢这个解决方案,因为它看起来非常非常黑客(我不相信整个框架/语言没有提供处理nobombed字符串的方法)。那么你知道另一种方法吗?否则,我将继续上述。
感谢@chris,@hakre和@jacob的时间!
更新3(液):原来,毕竟,这是一个浏览器的东西:它是不够添加header('Content-type: text/html; charset=UTF-8')
和meta标签,如<meta http-equiv="Content-type" value="text/html; charset=UTF-8" />
。它也必须正确地包含在<html><body>
部分,否则浏览器无法正确理解编码。感谢@jake提供的建议。
故事的士气:在尝试编码浏览器之前,我应该学习更多关于html的知识。感谢大家的帮助和耐心。
我建议你发布样本字符串(拆分之前和之后)以供检查的人员使用。为了保护他们二进制安全,base64_encode()他们,否则细节不会通过网页浏览器和stackoverflow等保存... – goat
@chris +1看来,与base64你可能会到东西 – bottlenecked
东西是真的这里奇怪。我总是在PHP中使用没有BOM的UTF8字符串,它没有任何问题。你如何输出变量?你只是'echo $ line'?您输出的是整个网页,即文档类型,标题等?或者你是否在命令行上使用PHP? –