Ao executar meu script, estou recebendo vários erros como este:
Aviso: Não é possível modificar as informações do cabeçalho - os cabeçalhos já enviados por ( saída iniciada em /some/file.php:12 ) em /some/file.php na linha 23
As linhas mencionadas nas mensagens de erro contêm header()
e setcookie()
chama.
Qual poderia ser a razão disso? e como consertar isso?
ob_start
eob_end_clean()
pode ser útil aqui). Você pode então definir um cookie ou sessão igual aob_get_contents()
e depois usarob_end_clean()
para limpar o buffer.safeRedirect
função no meu Biblioteca PHP: github.com/heinkasner/PHP-Library/blob/master/extra.phpUTF-8
, masUTF-8 (Without BOM)
~~~~~~~~~~~Respostas:
Nenhuma saída antes de enviar cabeçalhos!
As funções que enviam / modificam cabeçalhos HTTP devem ser chamadas antes que qualquer saída seja feita . summary ⇊ Caso contrário, a chamada falhará:
Algumas funções que modificam o cabeçalho HTTP são:
header
/header_remove
session_start
/session_regenerate_id
setcookie
/setrawcookie
A saída pode ser:
Não intencional:
<?php
ou depois?>
Intencional:
print
,echo
E outras funções de produção de saída<html>
seções antes<?php
de código.Por que isso acontece?
Para entender por que os cabeçalhos devem ser enviados antes da saída, é necessário analisar uma resposta HTTP típica . Os scripts PHP geram principalmente conteúdo HTML, mas também transmitem um conjunto de cabeçalhos HTTP / CGI para o servidor da web:
A página / saída sempre segue os cabeçalhos. O PHP precisa passar os cabeçalhos para o servidor da web primeiro. Só pode fazer isso uma vez. Após a quebra de linha dupla, ele nunca mais poderá alterá-los.
Quando o PHP recebe a primeira saída (
print
,echo
,<html>
) vai expulsar todos os cabeçalhos recolhidos. Depois, ele pode enviar toda a saída que desejar. Mas enviar cabeçalhos HTTP adicionais é impossível então.Como você pode descobrir onde ocorreu a saída prematura?
O
header()
aviso contém todas as informações relevantes para localizar a causa do problema:Aqui "linha 100" refere-se ao script em que a
header()
chamada falhou.A nota " saída iniciada em " entre parênteses é mais significativa. Denomina a fonte da saída anterior. Neste exemplo, é
auth.php
e linha52
. É aí que você precisa procurar resultados prematuros.Causas típicas:
Imprimir, eco
A saída intencional de
print
eecho
instruções encerrará a oportunidade de enviar cabeçalhos HTTP. O fluxo do aplicativo deve ser reestruturado para evitar isso. Use funções e esquemas de modelos. Verifique se asheader()
chamadas ocorrem antes que as mensagens sejam gravadas.As funções que produzem saída incluem
print
,echo
,printf
,vprintf
trigger_error
,ob_flush
,ob_end_flush
,var_dump
,print_r
readfile
,passthru
,flush
,imagepng
,imagejpeg
entre outros e funções definidas pelo usuário.
Áreas HTML brutas
Seções HTML não analisadas em um
.php
arquivo também são saída direta. As condições de script que acionarão umaheader()
chamada devem ser observadas antes de qualquer<html>
bloco bruto .Use um esquema de modelo para separar o processamento da lógica de saída.
<?php
Espaço em branco antes para avisos "script.php line 1 "Se o aviso se referir à saída em linha
1
, é principalmente espaço em branco , texto ou HTML antes do<?php
token de abertura .Da mesma forma, isso pode ocorrer para scripts anexados ou seções de script:
Na verdade, o PHP consome uma única quebra de linha após fechar tags. Mas não compensará várias novas linhas, guias ou espaços alterados para essas lacunas.
BOM UTF-8
Quebras de linha e espaços por si só podem ser um problema. Mas também existem seqüências de caracteres "invisíveis" que podem causar isso. O mais famoso é o UTF-8 BOM (Byte-Order-Mark), que não é exibido pela maioria dos editores de texto. É a sequência de bytes
EF BB BF
, que é opcional e redundante para documentos codificados em UTF-8. O PHP, no entanto, deve tratá-lo como saída bruta. Pode aparecer como os caracteres
na saída (se o cliente interpretar o documento como latino-1) ou "lixo" semelhante.Em particular, editores gráficos e IDEs baseados em Java são alheios à sua presença. Eles não o visualizam (obrigados pelo padrão Unicode). A maioria dos editores de programadores e consoles, no entanto, faz:
É fácil reconhecer o problema desde o início. Outros editores podem identificar sua presença em um menu de arquivo / configurações (o Notepad ++ no Windows pode identificar e solucionar o problema ). Outra opção para inspecionar a presença das listas técnicas está recorrendo a um hexeditor . Em sistemas * nix
hexdump
geralmente está disponível, se não uma variante gráfica que simplifica a auditoria desses e de outros problemas:Uma solução fácil é configurar o editor de texto para salvar arquivos como "UTF-8 (sem BOM)" ou uma nomenclatura semelhante. Geralmente, os recém-chegados recorrem à criação de novos arquivos e apenas copiam e colam o código anterior novamente.
Utilitários de correção
Também existem ferramentas automatizadas para examinar e reescrever arquivos de texto (
sed
/awk
ourecode
). Para PHP especificamente, há aphptags
tag mais arrumada . Ele reescreve as tags fechadas e abertas em formas longas e curtas, mas também corrige facilmente problemas de espaço em branco à esquerda e à direita, Unicode e UTF-x BOM:É sensato usar em um diretório inteiro de inclusão ou projeto.
Espaço em branco depois
?>
Se a fonte do erro for mencionada como atrás do fechamento
?>
, é aqui que alguns espaços em branco ou texto bruto serão gravados. O marcador final do PHP não termina a execução do script neste momento. Quaisquer caracteres de texto / espaço depois dele serão gravados como conteúdo da página.É geralmente recomendado, em particular para os novatos, que as
?>
tags de fechamento do PHP à direita sejam omitidas. Isso evita uma pequena parte desses casos. (Geralmente, osinclude()d
scripts são os culpados.)Origem do erro mencionada como "Desconhecido na linha 0"
Geralmente, é uma extensão do PHP ou configuração do php.ini se nenhuma fonte de erro for concretizada.
gzip
configuração de codificação de fluxo ou oob_gzhandler
.extension=
módulo duplamente carregado que gere uma mensagem implícita de inicialização / aviso do PHP.Mensagens de erro anteriores
Se outra instrução ou expressão PHP causar a impressão de uma mensagem ou aviso de aviso, isso também conta como saída prematura.
Nesse caso, você precisa evitar o erro, atrasar a execução da instrução ou suprimir a mensagem com, por exemplo,
isset()
ou@()
- quando um deles não obstrui a depuração posteriormente.Nenhuma mensagem de erro
Se você tiver
error_reporting
oudisplay_errors
desativado porphp.ini
, nenhum aviso será exibido. Mas ignorar erros não fará com que o problema desapareça. Cabeçalhos ainda não podem ser enviados após saída prematura.Portanto, quando os
header("Location: ...")
redirecionamentos falham silenciosamente, é aconselhável verificar se há avisos. Reative-os com dois comandos simples no topo do script de chamada:Ou
set_error_handler("var_dump");
se tudo mais falhar.Falando em cabeçalhos de redirecionamento, você deve usar um idioma como este para os caminhos finais do código:
De preferência, mesmo uma função de utilitário, que imprime uma mensagem do usuário em caso de
header()
falhas.Buffer de saída como solução alternativa
O buffer de saída do PHP é uma solução alternativa para aliviar esse problema. Geralmente funciona de maneira confiável, mas não deve substituir a estruturação adequada do aplicativo e a separação da saída da lógica de controle. Seu objetivo real é minimizar as transferências fragmentadas para o servidor da web.
A
output_buffering=
configuração, no entanto, pode ajudar. Configure-o no php.ini ou via .htaccess ou mesmo .user.ini nas configurações modernas do FPM / FastCGI.Ativá-lo permitirá que o PHP armazene em buffer a saída em vez de passá-la ao servidor da web instantaneamente. Assim, o PHP pode agregar cabeçalhos HTTP.
Da mesma forma, ele pode ser envolvido com uma chamada para o
ob_start();
topo do script de chamada. No entanto, o que é menos confiável por vários motivos:Mesmo que
<?php ob_start(); ?>
o primeiro script seja iniciado, o espaço em branco ou uma BOM podem ser embaralhados antes, tornando-o ineficaz .Pode ocultar espaços em branco para a saída HTML. Mas assim que a lógica do aplicativo tenta enviar conteúdo binário (uma imagem gerada, por exemplo), a saída estranha em buffer se torna um problema. (
ob_clean()
Necessário como solução alternativa mais avançada.)O tamanho do buffer é limitado e pode exceder facilmente quando deixado como padrão. E isso também não é uma ocorrência rara, difícil de rastrear quando acontece.
Portanto, ambas as abordagens podem se tornar não confiáveis - principalmente ao alternar entre configurações de desenvolvimento e / ou servidores de produção. É por isso que o buffer de saída é amplamente considerado apenas uma muleta / estritamente uma solução alternativa.
Veja também o exemplo de uso básico no manual e para mais prós e contras:
Mas funcionou no outro servidor !?
Se você não recebeu um aviso dos cabeçalhos antes, a configuração do buffer de saída do php.ini foi alterada. Provavelmente não está configurado no servidor atual / novo.
Verificando com
headers_sent()
Você sempre pode usar
headers_sent()
para investigar se ainda é possível ... enviar cabeçalhos. O que é útil para imprimir condicionalmente uma informação ou aplicar outra lógica de fallback.Soluções alternativas úteis são:
<meta>
Tag HTMLSe seu aplicativo for estruturalmente difícil de corrigir, uma maneira fácil (mas um pouco não profissional) de permitir redirecionamentos é injetar uma
<meta>
tag HTML . É possível obter um redirecionamento com:Ou com um pequeno atraso:
Isso leva ao HTML inválido quando utilizado após a
<head>
seção. A maioria dos navegadores ainda o aceita.Redirecionamento de JavaScript
Como alternativa, um redirecionamento JavaScript pode ser usado para redirecionamentos de página:
Embora geralmente seja mais compatível com HTML do que a
<meta>
solução alternativa, incorre em dependência de clientes compatíveis com JavaScript.Ambas as abordagens, no entanto, fazem fallbacks aceitáveis quando as chamadas genuínas de cabeçalho HTTP () falham. Idealmente, você sempre combinaria isso com uma mensagem amigável e um link clicável como último recurso. (Que, por exemplo, é o que a extensão PECL http_redirect () faz.)
Por que
setcookie()
esession_start()
também são afetadosAmbos
setcookie()
esession_start()
precisam enviar umSet-Cookie:
cabeçalho HTTP. Portanto, as mesmas condições se aplicam e mensagens de erro semelhantes serão geradas para situações de saída prematura.(É claro que eles também são afetados por cookies desabilitados no navegador ou até mesmo por problemas de proxy. A funcionalidade da sessão obviamente também depende do espaço livre em disco e de outras configurações do php.ini, etc.)
Links adicionais
fonte
?>
do final de um arquivo php geralmente é uma boa prática que ajuda a minimizar esses erros também. Espaço em branco indesejado não ocorrerá no final dos arquivos, e você ainda poderá adicionar cabeçalhos à resposta posteriormente. Também é útil se você usar o buffer de saída e não desejar adicionar espaços em branco indesejados no final das partes geradas pelos arquivos incluídos.Essa mensagem de erro é acionada quando qualquer coisa é enviada antes de você enviar cabeçalhos HTTP (com
setcookie
ouheader
). Os motivos comuns para a saída de algo antes dos cabeçalhos HTTP são:Espaço em branco acidental, geralmente no início ou no final dos arquivos, assim:
Para evitar isso, basta deixar de fora o fechamento
?>
- não é necessário de qualquer maneira.3F 3C
. Você pode remover com segurança a lista técnicaEF BB BF
desde o início dos arquivos.echo
,printf
,readfile
,passthru
, código antes<?
etc.display_errors
propriedade php.ini estiver configurada. Em vez de travar com um erro de programador, o php corrige silenciosamente o erro e emite um aviso. Enquanto você pode modificar as configuraçõesdisplay_errors
ou error_reporting , você deve corrigir o problema.Razões comuns são acessos a elementos indefinidos de uma matriz (como
$_POST['input']
sem usarempty
ouisset
para testar se a entrada está configurada) ou usar uma constante indefinida em vez de uma string literal (como$_POST[input]
, observe as aspas ausentes).Ativar o buffer de saída deve resolver o problema; toda a saída após a chamada para
ob_start
é armazenada em buffer na memória até você liberar o buffer, por exemplo, comob_end_flush
.No entanto, embora o buffer de saída evite os problemas, você realmente deve determinar por que seu aplicativo gera um corpo HTTP antes do cabeçalho HTTP. Seria como atender um telefonema e discutir o seu dia e o clima antes de dizer ao chamador que ele está com o número errado.
fonte
Eu recebi esse erro muitas vezes antes e tenho certeza de que todos os programadores PHP receberam esse erro pelo menos uma vez antes.
Possível solução 1
Este erro pode ter sido causado pelos espaços em branco antes do início do arquivo ou após o final do arquivo. Esses espaços em branco não devem estar aqui.
ex) NÃO DEVERÁ ESPAÇOS EM BRANCO
Verifique todos os arquivos associados ao arquivo que causa esse erro.
Nota: Às vezes, o EDITOR (IDE), como o gedit (um editor padrão do linux), adiciona uma linha em branco no arquivo salvo. Isso não deveria acontecer. Se você estiver usando Linux. você pode usar o editor VI para remover espaço / linhas após?> no final da página.
Solução possível 2: Se esse não for o seu caso, use ob_start para buffer:
Isso ativará o buffer de saída e seus cabeçalhos serão criados após o buffer da página.
fonte
ob_start()
apenas esconde o problema; não o use para resolver esse problema específico.ob_start()
, em seguida, o que devo fazer para resolver este problema:Headers already sent
ob_start()
não "esconde" o problema, resolve o problema.Em vez da linha abaixo
Escreva
ou
Definitivamente resolverá seu problema. Eu enfrentei o mesmo problema, mas resolvi através da localização do cabeçalho de escrita da maneira acima.
fonte
Você faz
antes de definir os cookies, o que não é permitido. Você não pode enviar nenhuma saída antes dos cabeçalhos, nem mesmo uma linha em branco.
fonte
É por causa desta linha:
Você não deve imprimir / repetir nada antes de enviar os cabeçalhos.
fonte
PROBLEMAS COMUNS:
(copiado de: fonte )
====================
1) não deve haver nenhuma saída (isto é,
echo..
códigos HTML) antes doheader(.......);
comando.2) remova qualquer espaço em branco (ou nova linha ) antes
<?php
e depois das?>
tags.3) REGRA DOURADA! - verifique se esse arquivo php (e também, se você tiver
include
outros arquivos) tem UTF8 sem codificação BOM (e não apenas UTF-8 ). Esse é um problema em muitos casos (porque o UTF8 arquivo codificado em possui algo especial no início do arquivo php, que seu editor de texto não mostra) !!!!!!!!!!!4) Depois que
header(...);
você deve usarexit;
5) sempre use a referência 301 ou 302:
6) Ative o relatório de erros e encontre o erro. Seu erro pode ser causado por uma função que não está funcionando. Quando você ativa o relatório de erros, sempre deve primeiro corrigir o erro máximo. Por exemplo, pode ser "Aviso: date_default_timezone_get (): não é seguro confiar nas configurações de fuso horário do sistema". - mais abaixo, você verá o erro "cabeçalhos não enviados". Depois de corrigir o erro mais alto (1º), recarregue sua página. Se você ainda tiver erros, corrija novamente o erro mais alto.
7) Se nenhuma das opções acima ajudar, use o redirecionamento JAVSCRIPT (no entanto, método fortemente não recomendado), pode ser a última chance em casos personalizados ...:
fonte
301
ou302
importante?Uma dica simples: um espaço simples (ou caractere especial invisível) em seu script, logo antes da primeira
<?php
tag, pode causar isso! Especialmente quando você está trabalhando em equipe e alguém está usando um IDE "fraco" ou mexeu nos arquivos com editores de texto estranhos.Eu já vi essas coisas;)
fonte
Outra má prática pode invocar esse problema que ainda não foi declarado.
Veja este trecho de código:
As coisas estão bem, certo?
E se "a_important_file.php" for este:
Isso não vai funcionar? Por que? Porque já uma nova linha é gerada.
Agora, embora esse não seja um cenário comum, e se você estiver usando uma estrutura MVC que carrega muitos arquivos antes de entregar coisas ao seu controlador? Este não é um cenário incomum. Esteja preparado para isso.
Do PSR-2 2.2:
Unix LF (linefeed) line ending
.single blank line
.omitted
de arquivos contendoonly php
Acredite em mim, seguir esses padrões pode poupar muitas horas da sua vida :)
fonte
?>
tag em qualquer arquivo em qualquer caso, de forma algumaCR LF
(típico fim de linha do Windows). Eu o resolvo baixando o arquivo original do repositório Wordpress que possuiLF
(fim de linha do Linux) em vez deCR LF
e também mudei minha função para o theme functions.php. Baseado em: bit.ly/1Gh6mzN?>
<?php
, removendo e adicionando uma única linha em branco, adicionando e omitindo a marca de fechamento?>
. No Windows + Wamp, todas essas combinações funcionam bem. Wierd ...Às vezes, quando o processo dev possui estações de trabalho WIN e sistemas LINUX (hospedagem) e no código você não vê nenhuma saída antes da linha relacionada, pode ser a formatação do arquivo e a falta do final da linha Unix LF (linefeed) .
O que geralmente fazemos para corrigir rapidamente isso é renomear o arquivo e, no sistema LINUX, criar um novo arquivo em vez do renomeado e, em seguida, copiar o conteúdo para ele. Muitas vezes, isso resolve o problema, pois alguns dos arquivos criados no WIN uma vez movidos para a hospedagem causam esse problema.
Essa correção é fácil para sites gerenciados por FTP e, às vezes, pode economizar algum tempo para nossos novos membros da equipe.
fonte
Geralmente, esse erro ocorre quando enviamos o cabeçalho após eco ou impressão. Se esse erro ocorrer em uma página específica, verifique se a página não está ecoando nada antes de ligar para
start_session()
.Exemplo de erro imprevisível:
Mais um exemplo:
Conclusão: Não produza nenhum caractere antes de chamar
session_start()
ouheader()
funciona nem mesmo em espaço em branco ou em nova linhafonte