2

我有一个 PHP 脚本(在 Linux 服务器上运行)输出服务器上某些文件的名称。它以简单的纯文本格式输出这些文件名。

此输出是使用 HttpWebRequest、HttpWebResponse 和 StreamReader 从 VB.NET 程序中读取的。

问题是一些正在输出的文件名包含......不寻常的字符。具体来说,“节”符号(§)。

如果我在 Web 浏览器中查看 PHP 脚本的输出,则该符号看起来很好。

但是,当我将 PHP 脚本的输出读入我的 .NET 程序时,符号显示不正确(它显示为通用“块”符号)。

我已经尝试了在读取响应流(来自 HttpWebResponse)时可以使用的所有不同字符编码选项。我尝试将流直接输出到文本文件(不好),在 TextBox 中显示(不好),即使直接在 Visual Studio 调试器中查看结果,字符也会显示为块而不是“节”符号。

我已经检查了十六进制编辑器中的输出(正如相关问题所建议的那样,“你如何解决字符编码问题。”

当我从 .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()

有任何想法吗?

  • 我是否使用了错误类型的 StreamReader?(我尝试在调用中传递字符编码以创建新的 StreamReader - 我已经尝试了 System.Text.Encoding 中的所有字符编码 - UTF-8、UTF-7、ASCII、UTF-32、Unicode、 ETC。)
  • 我应该使用不同的方法来读取 PHP 脚本的输出吗?
  • 输出文本时,我应该在 PHP 端做些什么不同的事情吗?

更新信息:

  • PHP 的输出通过调用专门编码为 UTF-8:utf8_encode($file);
  • 当我从 .NET 中写出符号时,我从 Windows 中的 Character Map 应用程序中复制并粘贴了该符号。我还直接从文件名(在 Windows 中)和此网页本身复制并粘贴了它 - 写出时都给出了相同的十六进制值(c2 a7)。
  • 是的,我说的“部分符号”是 U+00A7(Windows 上的 ALT+0167,根据字符映射表)。
  • 内容类型是通过header('Content-Type: text/html; charset=utf-8');PHP 脚本开头的右侧显式设置的。

更新:

我自己想出来了,但如果没有回答的人的帮助,我是做不到的。谢谢!

4

4 回答 4

2

弄清楚了!!

就像很多事情一样,回想起来很简单!

Jon Skeet 是正确的——它应该是 UTF-8,但绝对不是。

事实证明,在我使用的原始脚本中(在我将其剥离以使其更易于调试之前),脚本有一些额外的文本输出没有包含在utf8_encode()调用中。这导致整个页面以 ISO-8859-1 而不是 UTF-8 输出。

当我检查我的测试脚本的“编码”属性(在 Firefox 中,“查看页面信息”)时,我注意到了这一点。测试脚本是 UTF-8,但是 ISO-8859-1。生产脚本还打印了文件的日期;这没有包含在对 utf8_encode 的调用中——这导致整个输出更改为 ISO-08859-1。

[在这里插入我拍脑门的声音]

感谢所有回答的人!你很有帮助!

于 2008-12-15T17:30:57.977 回答
1

PHP 是否让您完全控制编码?仅仅猜测它通常不是一个好主意。

当您说您已经从 .NET 中写出符号时,您使用的是什么编码?它是什么实际的 Unicode 代码点?unicode U+00A7处有一个节符号- 是你的意思吗?我不知道为什么 PHP 会将其表示为“ef bf bd”。

使用 StreamReader 应该没问题,但您需要知道正确的编码。

编辑:好的,所以它应该是 UTF-8,当然不是 - 所以问题出在 PHP 方面。如果您运行utf8_encode($file)然后显式打印出结果的字节(没有 Web 服务器妨碍)会发生什么?我真的很惊讶浏览器设法获得正确的符号......这只是普通的HTML吗?您确定所有“ef bf bd”都只是节符号吗?

这个网络服务器在任何地方都是公开的吗?如果我可以将浏览器指向它,我也许可以弄清楚发生了什么。

于 2008-12-15T16:06:34.603 回答
1

您正在使用utf8_encode($file),很好,但是 PHP 是否也将内容类型返回为 UTF-8?你能检查Content-Type你的 PHP 页面返回的标题吗?您应该特别查看该charset字段以确保您拥有以下内容:

Content-Type: text/html; charset=utf-8

我可以看到浏览器如何在 .NET(正确或错误)失败时正确显示字符。浏览器通常会尝试尽可能地健壮和宽容。您使用的浏览器可能会从字符序列中推断出实际的字符编码。

于 2008-12-15T16:34:55.407 回答
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

然后,这将加载到文件中并将其作为另一个文件返回给您,您可以将其加载到其他文件中,例如屏幕阅读器。您可以类似地修改它以读取字符串或任何其他包含问题代码的内容。

于 2012-02-06T15:10:56.773 回答