我有一个PHP脚本(在Linux服务器上运行),它输出服务器上某些文件的名称。它以简单的纯文本格式输出这些文件名。
使用HttpWebRequest,HttpWebResponse和StreamReader从VB.NET程序读取此输出。
问题是输出的某些文件名包含......不常见的字符。具体来说,“部分”符号(§)。
如果我在Web浏览器中查看PHP脚本的输出,则符号显示正常。
但是当我将PHP脚本的输出读入我的.NET程序时,该符号没有正确显示(它显示为通用的“块”符号)。
我已经尝试了在读取响应流时可以使用的所有不同的字符编码选项(来自HttpWebResponse)。我已经尝试将流直接输出到文本文件(不好),在TextBox中显示它(不好),甚至直接在Visual Studio调试器中查看结果时,字符显示为块而不是“部分”符号。
我已经在十六进制编辑器中检查了输出(正如相关问题“how do you troubleshoot character encoding problems”所示。
当我从.NET本身写出部分符号(§)时,我看到代表它的十六进制字节是“c2 a7”(如果它是unicode就有意义,对吗?需要两个字节?)。当我将PHP脚本的输出直接写入文件并使用十六进制编辑器检查时,符号显示为“ef bf bd” - 三个字节而不是两个?
我不知道该怎么做 - 如果我需要指定其他一些字符编码,或者我错过了一些明显的事情。
以下是用于获取PHP脚本输出的代码(修改了VB样式的注释,以便它们在此站点上正确显示):
Dim myRequest As HttpWebRequest = WebRequest.Create("http://www.example.com/sample.php")
Dim myResponse As HttpWebResponse = myRequest.GetResponse()
// read the response stream
Dim myReader As New StreamReader(myResponse.GetResponseStream())
// read the entire output in one block (just as an example)
Dim theOutput as String = myReader.ReadToEnd()
有什么想法吗?
更新信息:
utf8_encode($file);
header('Content-Type: text/html; charset=utf-8');
显式设置。更新
自己想出来,但如果没有得到回答的人的帮助,我就无法做到。谢谢!
答案 0 :(得分:2)
弄清楚!!
像很多东西一样,回想起来很简单!
Jon Skeet是正确的 - 意味着是UTF-8,但绝对不是。
事实证明,在我使用的原始脚本中(在我将其剥离以使其更易于调试之前),脚本中还有一些其他文本输出未包含在utf8_encode()
调用中。这导致整个页面以ISO-8859-1而不是UTF-8输出。
当我检查测试脚本的“编码”属性时(在Firefox中,“查看页面信息”),我注意到了这一点。测试脚本是UTF-8,但ISO-8859-1。生产脚本还打印了文件的日期;这并没有包含在对utf8_encode的调用中 - 这导致整个输出更改为ISO-08859-1。
[插入我的额头拍打我的额头]
感谢所有回答的人!你非常乐于助人!
答案 1 :(得分:1)
PHP能让你控制编码吗?只是猜测它通常不是一个好主意。
当你说你已经从.NET写出符号时,你使用了什么编码?它是什么实际的Unicode代码点? unicode U+00A7处有一个部分符号 - 是你的意思吗?我不知道为什么PHP会将其表示为“ef bf bd”。
使用StreamReader应该没问题,但您需要知道正确的编码。
编辑:好的,所以意味着是UTF-8,当然不是 - 所以问题出在PHP方面。如果你运行utf8_encode($file)
然后显式打印结果的字节(没有Web服务器妨碍)会发生什么?我真的很惊讶浏览器正在设法获得正确的符号......这只是简单的HTML吗?你确定所有“ef bf bd”只是部分符号吗?
此网络服务器是否在任何地方公开?如果我可以将浏览器指向它,我可能能够解决正在发生的事情。
答案 2 :(得分:1)
您正在使用utf8_encode($file)
,很好,但是PHP也将内容类型返回为UTF-8吗?你能检查PHP页面返回的Content-Type
标题吗?你应该特别注意charset
字段,以确保你有这样的东西:
Content-Type: text/html; charset=utf-8
我可以看到浏览器在.NET(正确或错误地)失败时如何正确显示角色。浏览器通常尽量保持健壮和宽容。您正在使用的浏览器可能会从字符序列中推断出实际的字符编码。
答案 3 :(得分:0)
使用上面的建议我创建了一个简单的解决方案,即创建一个包含以下内容的文件:
$feed = header("Content-Type: text/html; charset=utf-8");
$feed.=utf8_encode(readfile(rawurldecode($_GET["url"])));
$feed = fread(rawurldecode($_GET["url"]));
die($feed);
这是PHP,但可以轻松移植到任何其他语言。然后你只需调用你想要使用的任何导致UTF8问题的URL(我发现RSS源存在问题,因此我需要它),URL中的问题文件的URL获取变量,如http://example.com/fix-my-rss.php?url=http://anotherexample.com/broken.rss < / p>
然后,这将加载到文件中,并将其作为另一个文件返回给您,而不会出现问题,您可以将其加载到其他内容中,例如屏幕阅读器。您可以类似地修改它以读取字符串或其他任何有问题代码的地方。