codificação de caracteres problema - a saída PHP, lido por NET, via HttpWebRequest

votos
2

Eu tenho um script PHP (rodando em um servidor Linux) que Ouputs os nomes de alguns arquivos no servidor. Ele produz esses nomes de arquivo em um formato só de texto simples.

Esta saída é lido a partir de um programa VB.NET usando HttpWebRequest, HttpWebResponse e um StreamReader.

O problema é que alguns dos nomes de ficheiros estão a ser enviados contêm ... personagens incomuns. Especificamente, o símbolo seção (§).

Se eu ver a saída do script PHP em um navegador web, o símbolo aparece bem.

Mas quando li a saída do script PHP em meu programa NET, o símbolo não aparece corretamente (ele aparece como um símbolo genérico block).

Eu tentei todas as diferentes opções de codificação de caracteres que você pode usar ao ler o fluxo de resposta (do HttpWebResponse). Eu tentei produzir o fluxo diretamente para um arquivo de texto (não é bom), exibi-lo em uma caixa de texto (não é bom), e até mesmo ao ver os resultados diretamente no depurador Visual Studio, o personagem aparece como um bloco em vez de como o símbolo seção.

Eu examinei a saída em um editor hexadecimal (como sugerido por uma questão relacionada, como é que você solucionar problemas de codificação de caracteres .

Quando eu escrever o símbolo de seção (§) da própria NET, os bytes hexadecimais vejo que a representam são a7 c2 (faz sentido se for unicode, certo? Requer dois bytes?). Quando eu escrever a saída do script PHP diretamente para um arquivo e examinar isso com um editor hexadecimal, o símbolo mostra-se como ef bf bd - três bytes em vez de dois?

Eu estou em uma perda sobre o que fazer - se eu precisar especificar alguma outra codificação de caracteres, ou se eu estou faltando alguma coisa óbvia sobre isso.

Aqui está o código que é usado para obter a saída do script PHP (comentários VB-estilo modificado para que eles apareçam corretamente neste site):


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()

Alguma ideia?

  • Estou usando o tipo errado de StreamReader? (Eu tentei passar a codificação de caracteres na chamada para criar o novo StreamReader - Eu tentei todos os que estão em System.Text.Encoding - UTF-8, UTF-7, ASCII, UTF-32, Unicode, etc)
  • Deveria eu estar usando um método diferente para ler a saída do script PHP?
  • Existe algo que eu deveria estar fazendo diferente no lado do PHP o quando a saída do texto?

INFO ATUALIZADO:

  • A saída do PHP é especificamente codificado UTF-8 chamando: utf8_encode($file);
  • Quando escrevi o símbolo da NET, Copiei e colei o símbolo do aplicativo Character Map no Windows. Também copiei e colei diretamente do nome do arquivo (no Windows) e desta página web em si - todos deram o mesmo valor hexadecimal quando escrito (a7 c2).
  • Sim, o símbolo da seção Eu estou falando é U + 00A7 (ALT + 0167 no Windows, de acordo com o mapa de caracteres).
  • O tipo de conteúdo é definido explicitamente via header('Content-Type: text/html; charset=utf-8');logo no início do script PHP.

ATUALIZAR:

Descobri-lo eu mesmo, mas eu não poderia ter feito isso sem a ajuda das pessoas que responderam. Obrigado!

Publicado 15/12/2008 em 17:02
fonte usuário
Em outras línguas...                            


4 respostas

votos
2

Descobri-lo !!

Como tantas coisas, é simples em retrospectiva!

Jon Skeet estava correta - foi destinado para ser UTF-8, mas definitivamente não era.

Acontece que, no roteiro original que eu estava usando (antes de eu despojado-lo para torná-lo mais simples de depuração), houve alguma saída de texto adicional pelo script que não foi envolvido em uma utf8_encode()chamada. Isto fez com que toda a página a ser debitada na norma ISO-8859-1 em vez de UTF-8.

Percebi isso quando eu chequei propriedade "codificação" do meu script de teste (no Firefox, "Ver página Info"). Foi UTF-8 para o script de testes, mas ISO-8859-1. O script de produção também impressa a data do arquivo; isto não foi envolvido em uma chamada para utf8_encode - e que causou a saída inteira para mudar para ISO-08859-1.

[Insira som de mim tapa minha testa aqui]

Obrigado a todos que responderam! Você foi muito útil!

Respondeu 15/12/2008 em 18:30
fonte usuário

votos
1

Você está usando utf8_encode($file), bem, mas é PHP retornando o tipo de conteúdo como UTF-8 também? Você pode verificar o Content-Typecabeçalho retornado por sua página PHP? Você deve sobretudo olhar para o charsetcampo para se certificar de que você tem algo como isto:

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

Eu posso ver como um navegador pode estar exibindo o caráter corretamente ao .NET (legitimamente ou injustamente) falhar. Browsers geralmente tentam ser tão robusto e tolerante quanto possível. O navegador que você está usando pode ser inferir a codificação de caracteres real a partir das sequências de caracteres.

Respondeu 15/12/2008 em 17:34
fonte usuário

votos
1

O PHP dará controle sobre a codificação em tudo? Geralmente não é uma boa idéia para apenas adivinhar-lo.

Quando você diz que você escreveu para fora o símbolo da NET, que codificação você estava usando? O actual ponto de código Unicode é? Há um símbolo de seção em Unicode U + 00A7 - é que o que você quer dizer? Não tenho idéia por que PHP representaria que, como "bd ef bf" embora.

Usando um StreamReader deve estar bem, mas você precisa saber a codificação correta.

EDIT: Ok, então ele está destinado a ser UTF-8, e certamente não é - então o problema está no lado do PHP. Se você executar utf8_encode($file)e, em seguida, imprimir os bytes do resultado explicitamente (sem o servidor web ficando no caminho) o que acontece? Eu estou realmente surpreso que um navegador está conseguindo obter o símbolo direito embora ... é este HTML simplesmente? Tem a certeza de que todos "bd bf ef" é apenas o símbolo seção?

É este público servidor web em qualquer lugar? Se eu pudesse apontar meu navegador para ele, eu poderia ser capaz de descobrir o que está acontecendo.

Respondeu 15/12/2008 em 17:06
fonte usuário

votos
0

Usando o conselho acima Eu criei uma solução fácil que é criar um arquivo com o seguinte conteúdo:

$feed = header("Content-Type: text/html; charset=utf-8");
$feed.=utf8_encode(readfile(rawurldecode($_GET["url"])));
$feed = fread(rawurldecode($_GET["url"]));
die($feed);

Esta é PHP, mas pode ser facilmente portado para qualquer outro idioma. Então você simplesmente chamar qualquer URL que deseja usar que as questões UTF8 está causando (eu encontrei um problema com um feed RSS, portanto, a minha necessidade por ele) com a URL do arquivo problema em um URL obter variável como assim http: // exemplo. ? com / corrigir-meu-rss.php url = http: //anotherexample.com/broken.rss

Este, então, carregar no arquivo e devolvê-lo a você como um outro arquivo que sem o problema que você pode carregar em outra coisa, como um leitor de tela. Você poderia semelhante modificá-lo para ler uma corda ou qualquer outra coisa que você tem o código de problema no.

Respondeu 06/02/2012 em 16:10
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more