Como definir o cabeçalho HTTP para UTF-8 usando PHP, que é válido no validador W3C?


319

Eu tenho várias páginas PHP ecoando várias coisas em páginas HTML com o seguinte código.

<meta http-equiv="Content-type" content="text/html; charset=utf-8" />

No entanto, quando valido usando o validador W3C, ele aparece:

A codificação de caracteres especificada no cabeçalho HTTP (iso-8859-1) é diferente do valor no elemento (utf-8).

Eu sou bastante novo no PHP e estava pensando se poderia e deveria alterar o cabeçalho dos arquivos PHP para corresponder aos arquivos HTML.

Respostas:


897

Use headerpara modificar o cabeçalho HTTP:

header('Content-Type: text/html; charset=utf-8');

Observe para chamar esta função antes que qualquer saída seja enviada ao cliente. Caso contrário, o cabeçalho também foi enviado e você obviamente não poderá mais alterá-lo. Você pode verificar isso com headers_sent. Veja a página de manual deheader para mais informações.


4
Gostaria apenas de acrescentar que, quando você define o cabeçalho HTTP corretamente assim, não precisa mais da <meta>tag.
Jon

3
@ Jon: Eu usaria os dois. O equivalente a HTTP METAé usado quando o documento HTML não é carregado via HTTP (por exemplo, do disco).
Gumbo

6
Isso só funcionará se você estiver executando o php, para fazê-lo em páginas estáticas, você deve salvar o arquivo html AS utf-8. Fazer isso adicionará o caractere BOM utf-8 codificado ao início do arquivo. bytes 0xEF, 0xBB, 0xBF adicionados ao início do arquivo. A maioria dos servidores web notará isso e aplicará o cabeçalho apropriado. De fato, salvar o seu arquivo php como utf-8, faria a mesma coisa.
Rahly 25/11/10

1
@ Jeremy Walton: O acréscimo da lista técnica de UTF-8 não acontece necessariamente. De fato, nem é necessário para o UTF-8, pois ele possui apenas uma ordem de bytes (mas pode ser usado para identificar o UTF-8).
Gumbo

1
@ Gumbo: claro, estou simplificando aqui e direcionando o cenário da web de longe mais comum (a questão parece falar sobre esse cenário). Levando em conta o nível aparente da pergunta, por que fazer algo quando você nem entende quais são as vantagens que algum dia eles oferecem?
Jon


15

Esse é um problema com o servidor da Web enviando um cabeçalho HTTP que não corresponde ao que você define. Para obter instruções sobre como fazer o servidor enviar os cabeçalhos corretos, consulte esta página .

Caso contrário, você também pode usar o PHP para modificar os cabeçalhos, mas isso deve ser feito antes da saída de qualquer texto usando este código:

header('Content-Type: text/html; charset=utf-8');

Mais informações sobre como enviar cabeçalhos usando PHP podem ser encontradas na documentação da função de cabeçalho .


12

Você também pode usar uma maneira mais curta:

<?php header('Content-Type: charset=utf-8'); ?>

Veja RFC 2616 . É válido especificar apenas o conjunto de caracteres.


Eu gosto dessa opção, porque (presumo) permitiria definir a outra parte do tipo de conteúdo separadamente (por exemplo, você tem algumas páginas de texto / sem formatação e algumas páginas de texto / html, mas todas são UTF8). Meu entendimento está correto?
Eric Seastrand

1
Não consigo encontrar a parte da RFC 2616 que diz que é válido especificar dessa maneira. Content-Type = "Content-Type" ":" media-typeemedia-type = type "/" subtype *( ";" parameter )
AI0867 13/04

1
Não é válido especificar apenas o conjunto de caracteres. Não é válido pela RFC 2616 (que é de qualquer maneira obsoleta) nem pela RFC 7231 (que não é obsoleta) nem por qualquer outra RFC. Veja stackoverflow.com/questions/41994062/…
sideshowbarker

10

Para uma implementação correta, você precisa alterar uma série de coisas.

Banco de dados (imediatamente após a conexão):

mysql_query("SET NAMES utf8");

// Meta tag HTML (probably it's already set): 
meta charset="utf-8"
header php (before any output of the HTML):
header('Content-Type: text/html; charset=utf-8')
table-rows-charset (for each row):
utf8_unicode_ci

4
A coalizão do banco de dados não influencia a saída gerada pelo PHP porque os dados são codificados para o formato nativo configurado para uso com o PHP antes de retornar ao usuário. Em segundo lugar, o OP não mencionou que ele está usando o MySQL. Terceiro, o MyISAM está desatualizado e não deve ser recomendado, a menos que você saiba o que está fazendo. Existe uma razão para o InnoDB se tornar o novo padrão.
EWit

finalmente, uma lista completa de todos os locais para definir a codificação de caracteres.
JavaScript é necessário para o funcionamento completo desta página

mysql_query ("SET NAMES utf8"); antes de minha consulta de seleção corrigir o problema para mim. Obrigado :)
Deepak Goswami

7

O PHP envia cabeçalhos automaticamente se configurado para usar codificação interna:

ini_set('default_charset', 'utf-8');
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.