Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Rafael Augusto_173176

Erro Warning: session_start()

Recommended Posts

Pessoal criei o site de um cliente com login de usuario, mais no lacalhost nao tinha aparecido nenhum erro, tava perfeito.

mais quando subi o site ta aparecendo esse erro.

 

Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by on line 39

Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent on line 39

 

 

 

esse e o codigo que esta entre minha linha 38 ate a 40

 

 

 

if (!isset($_SESSION)) {
 session_start(); 
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cookies nada mais são do que informações que trafegam por dois cabeçalhos específicos, dependendo se estes vão para o servidor (Request) ou retornam dele (Response).

 

E sessões com cabeçalhos é aquela velha história (com H mesmo). Se algum cabeçalho já tiver sido enviado, ao iniciar a sessão vai dar problema.

 

Output, apesar de não ser um cabeçalho, também é incluído nessa restrição pois uma vez que um conteúdo seja ecoado, diversos outros cabeçalhos já foram enviados.

Compartilhar este post


Link para o post
Compartilhar em outros sites

A linha 39 foi que disparou o erro. Se você disse que aquelas três linhas são da 38 à 40, logo o gatilho é a função session_start().

 

Não vou entrar eum uma discussão épica que duraria dias quando a galera chegase por aqui. resumidamente, o que tem antes dessas linhas?

 

Tem algum echo, print, (v)(s)printf(f), alguma chamada à header(), BOM ou, quem sabe, algum HTML manualmente inserido ou mesmo um espaço em branco antes do <?php?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não tem como a session não estar startada antes do $_SESSION, o if é desnecessário. Coloque esse código na primeira linha do php e veja o que acontece.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não tem como a session não estar startada antes do $_SESSION, o if é desnecessário. Coloque esse código na primeira linha do php e veja o que acontece.

Não Khaos, verificar se $_SESSION existe antes de iniciar a sessão é quase mandatório para que a essão não seja iniciada duas vezes (o que também gera erro).

 

E a lógica sem lógica desse teste é culpa do próprio PHp que só cria esse superglobal depois de session_start(0 ter sido invocado com sucesso. Até antes disso ele sequer existe.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Esse erro deve ser o mais perguntado da história do fórum.. segue uma tradução (fiz rapidamente, deve conter erros) desta resposta completa e explicativa no StackOverflow:

 

Não emita output antes de enviar os headers!

 

Funções que enviam/modificam headers HTTP devem ser chamadas antes de que qualquer output seja feito. Caso contrário, a chamada falhará.

 

Warning: Cannot modify header information - headers already sent (output started at file:line)

 

Algumas funções que modificam os headers HTTP são:

Output pode ser:

  • Acidental:
  • Intencional:
    • print, echo e outras funções que emitem output (como var_dump)
    • Código <html> antes do código dentro de <?php.

Por que isso acontece?

 

Para entender porque os headers devem ser enviados antes do output, é necessário olhar uma típica HTTP Response. Scripts PHP geram conteúdo HTML principalmente, mas também passam alguns headers HTTP/CGI ao servidor.

HTTP/1.1 200 OK
Powered-By: PHP/5.3.7
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8

<html><head><title>PHP page output page</title></head>
<body><h1>Content</h1> <p>Some more output follows...</p>
and <a href="/"> <img src=about:note> ...

A página/output sempre segue os headers. O PHP é obrigado a passar os headers ao servidor primeiramente. Ele pode apenas fazer isto uma vez. E depois da quebra de linha dupla (envio de output p/ simplificar), ele não pode mais adicionar mais headers.

 

Quando o PHP recebe o primeiro output (print, echo, <html>), ele irá enviar os headers coletados. Mais tarde, ele pode enviar todos o conteúdo do output que quiser. Mas enviar novos headers não é possível a partir deste momento.

 

Como você pode descobrir onde o output ocorreu?

 

O warning da função header() contém todas as informações relevantes para localizar a raíz do problema:

 

Warning: Cannot modify header information - headers already sent by (output started at/www/usr2345/htdocs/auth.php:52) in /www/usr2345/htdocs/index.php on line 100

 

Aqui, a "line 100" refere-se à linha do script onde a chamada da função header() falhou.

A mensagem dentro dos parênteses é mais importante. Ela menciona que a linha 52 do arquivo auth.php é a raiz do output. Uma das causas mais populares deste erro são:

 

Print, echo

 

Output intencional de execuções print e echo vão acabar com a oportunidade de enviar headers HTTP. O fluxo da aplição deve ser reestruturado para evitar isso. Use funções e templates. Verifique se as chamadas para a função header() ocorrem antes de que as mensagens são enviadas.

 

Funções que podem enviar output incluem print, echo, printf, trigger_error, vprintf,ob_flush, var_dump, readfile, passthru, entre outras e também funções definidas por você.

 

Código HTML

 

Códigos HTML que não são interpretados em um arquivo .php são outputs também. Códigos que chamarão a função header() devem ser feitas antes de qualquer código <html>.

<!DOCTYPE html> <?php // Já não é possível enviar headers.

Espaços em branco antes de <?php quando "arquivo.php line 1" é mencionado

Se a mensagem diz que o erro está na linha 1, então é normalmente espaços em branco, texto ou HTML antes da abertura da tag <?php.

 <?php # Há um espaço/linha em branco antes de <?php

Podem igualmente ocorrer com scripts "juntos".

?> <?php

O PHP, na verdade, coloca uma quebra de linha depois de fechar as tags.

UTF-8 BOM

 

Quebras de linhas e espaços podem ser um problema. Mas também há sequências de caracteres "invisíveis" que podem causar isto. o mais popular é o UTF-8 BOM (Byte-Order-Mark) que não é exibido pela maioria dos editores de texto. É uma sequência de bytes, que é opcional e redundante para arquivos em UTF-8. Mas o interpretador do PHP o trata como output. Ele também pode mostrar como caracteres  no output (se o cliente interpreta o documento em Latin-1) ou algum "lixo" semelhante.

Particularmente, alguns editores gráficos e IDEs Java-based não notam sua presença. Elas não veem isso (obrigado pelo padrão Unicode). Entretanto, alguns editores e consoles mostram:

 

aXgWY.png

 

Não é fácil reconhecer o problema logo no início. Sem um editor desses disponível (ou Notepad++ no Windows, que pode resolver o problema), uma outra solução seria um hexeditor. Programadores deveriater um, pois eles simplificam a identificação desses problemas:

 

QyqUr.png

A solução fácil é definir o editor de texto usado para salvar arquivos como "UTF-8 (no BOM)" ou alguma outra nomenclatura semelhante. Muitos novos criam novos arquivos e copiam e colam o código anterior de volta.

 

Utilitários de correção

 

Há ferramentas automatizadas para reescrever arquivos de texto. Para o PHP, especificamente, há o phptags tag tidier. Ele reescreve tags de abertura e fechamento em tags longas e curtas, mas também resolve facilmente problemas de whitespace e BOM:

phptags --whitespace *.php

É sensato usar em um diretório completo ou no diretório do projeto.

 

Espaços em branco após ?>

 

Se a raiz do erro é mencionada depois do fechamento da ?>, então aí é onde há algum espaço em branco ou texto escrito. A tag de fechamento do PHP não termina a execução do script neste ponto. Quaisquer caracteres depois dela serão impressos como output.

É comumente dito aos novatos que a tag de fechamento deveria ser omitida. Isso evita uma parte significante destes casos. (Comumente includes são os culpados).


Novamente, phptags --whitespace *.php resolve isso rapidamente.


Igualmente o comando phptags --unclosed ./includes pode remover tags ?> redundantes dos scripts.

 

Raíz do erro mencionada como "Unknown on line 0"

 

Acontece tipicamente quando extensões PHP ou o php.ini definem se a raíz do erro não é especificada. Isso acontece principalmente com a gzip stream ou o ob_gzhandler. Porém isso também poderia ser qualquer módulo carregado duas vezes, que deixam uma mensagem de warning implícita.

 

Mensagens de erro anteriores

 

Se algum outro comando PHP causa uma warning ou notice sendo exibida, isso também conta como output. Neste casso, você precisa corrigir o erro, atrasar a execução do comando ou suprimir o erro com isset() ou @ - quando este não obstrui o debugging mais tarde.

 

Nenhuma mensagem de erro

 

Se você tem error_reporting ou display_errors desabilitados pelo php.ini, então nenhum warning será exibido. Mas ignorar erros não resolverão o problema :joia:. Mesmo assim, os headers não poderão ser enviados após o output.

 

Então, quando header("Location: ...") o redirecionamento falha silenciosamente, é bom examinar os warnings. Habilite-os novamente com dois comandos simples (no início do script):

error_reporting(E_ALL); ini_set("display_errors", 1);

Ou se todo o resto falhar:

set_error_handler("var_dump");

Falando de redirecionamentos, você deveria usar algo parecido com isso para caminhos de código no final.

exit(header("Location: /finished.html"));

Ou mesmo uma função, que imprima uma mensagem quando uma chamada header() falhar.

 

Controle de saída como gambiarra :skull:

 

O controle de saída do PHP é adequado para aliviar este problema. Isso não é tão confiável, mas deveria ser considerado uma gambiarra válida . Seu propósito real é minimizar transferências fragmentadas ao servidor. Reestruturar a aplicação para evitar output é preferível.

 

Todavia, faz a configuração output_buffering=. Configure isso no php.ini ou via.htaccess ou até mesmo .user.ini. Com isso habilidato, o conteúdo fica armazenado em buffer e não é instantaneamente passadi oara i servidor. Então headers HTTP podem ser agregados.

Isso pode também ser feito com uma chamada ao ob_start(); no topo do script. Isto, entretanto, é menos confiável por algumas razões:

  • Mesmo se <?php ob_start(); ?> começar o primeiro script, espaços em branco ou um problema de BOM podem ser ocasionados antes, tornando está técnica ineficiente.
  • Isso pode ocultar espaços em branco para output HTML; mas na medida em que a lógica da aplicação tenta enviar conteúdo binário (uma imagem gerada, por exemplo), o but as soon as the application logic attempts to send binary content (a generated image for example), os espaços irrelevantes armazenados em buffer tornam-se um problema. (apesar de que ob_clean() é uma outra gambiarra válida)
  • O buffer tem um limite de tamanho. Embora geralmente um problema hipotético, pode no entanto acontecer - o que não seria fácil de descobrir/examinar.

Veja também um exemplo básico de uso no manual.

 

Mas isso funcionou em um outro servidor!?

 

Se você não teve warnings antes, então a configuração do php.ini mudou. O controle de saída então estava habilitado no outro servidor, mas não no atual. Veja a seção anterior.

 

Verificando com headers_sent()

 

Você pode sempre usar headers_sent() para examinar se ainda é possível enviar headers. Isso é útil para condicionalmente mostrar uma informação ou aplicar alguma outra lógica.

if (headers_sent()) {
    die("O redirecionamento falhou. Por favor, clique neste link: <a href=...>");
}
else{
    exit(header("Location: /user.php"));
}

Gambiarra com a tag HTML <meta> :skull: :skull: :skull:

 

Se a estrutura da sua aplicação é estruturalmente difícil de corrigir, então uma forma fácil (mas amadora) de criar um redirecionamento é injetando HTML. Um redirecionamento pode ser feito assim:

<meta http-equiv="Location" content="http://example.com/">

Ou com um simples atraso (o sobrinho aprova!):

<meta http-equiv="Refresh" content="2; url=../target.html">

Isso tornará seu site inválido (mesmo com falso XHTML) quando inserido fora do <head>. A maioria dos browsers ainda aceitam isso. Como alternativa, um redirect em Javascript poderia ser feito:

<script> location.replace("target.html"); </script>

É uma abordagem aceitável se este é usado como um fallback pelas funções de redirecionamento especializadas, o qual deveria primeiro tentar enviar um header() propriamente dito, mas usar a meta tag e uma mensagem amigável e um link como último recurso.

 

Porque setcookie() e session_start() são também afetados

 

Tanto o setcookie() quanto o session_start() precisam enviar um header Set-Cookie. As mesmas condições portanto se aplicam e mensagens de erros semelhantes serão exibidas.

Problemas de output de headers não são a única causa para a não-funcionalidade com eles, é claro. Cookies desativados no navegador ou até mesmo problemas de proxy deveriam ser sempre verificados. A funcionalidade da session também depende do espaço livre em disco e de outras configurações do php.ini.

Compartilhar este post


Link para o post
Compartilhar em outros sites

P*rra! :o

 

Se o cara não entendeu o que eu disse no post #2 provavelmente não vai entender o post #6. Imagina então essa tese de doutorado de escola pública.

Compartilhar este post


Link para o post
Compartilhar em outros sites

P*rra! :o

 

Se o cara não entendeu o que eu disse no post #2 provavelmente não vai entender o post #6. Imagina então essa tese de doutorado de escola pública.

eu intendi o que vc explicou no post #2 e tbm intendi o que ele explicou no post #6 e ja resolvi meu problema

Compartilhar este post


Link para o post
Compartilhar em outros sites

eu intendi o que vc explicou no post #2 e tbm intendi o que ele explicou no post #6 e ja resolvi meu problema

 

Não foi isso que pareceu mas, em todo caso, não foi intenção ofender, se é que entendeu dessa maneira.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não foi isso que pareceu mas, em todo caso, não foi intenção ofender, se é que entendeu dessa maneira.

nao, desculpe se pareceu que interpletei de forma ofensiva, vc me ajudou muito tambem, eu so queria intender de forma mais funda o erro

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.