Ferramentas de Utilizador

Ferramentas de Site


dev_web:php:problemas_comuns_em_php

Problemas comuns em código PHP

Esta página visa a cobrir alguns dos problemas mais comuns que acontecem no PHP. Por vezes são problemas simples, mas muito questionados em fóruns, etc. Vamos ver cada um deles pormenorizadamente.

Headers already sent

Problema: O código de PHP está todo bonito, quando, do nada, surge uma mensagem a dizer que os headers já foram enviados, por exemplo, com o seguinte código:

echo "oi";
header("Location: outrapagina.php");

Irá dar o seguinte erro:

Warning: Cannot modify header information - headers already sent by (output started at C:wampwwwprobs.php:1) in C:wampwwwprobs.php on line 2

Esta mensagem é bastante explícita: indica que os headers não podem ser enviados porque já ocorreu um output na linha 1 (echo "oi";).

E o que são os tais headers? São cabeçalhos HTTP que são enviados para o cliente, com diversas informações, como a resposta do servidor (200 OK, 404 Not found), tamanho do ficheiro, etc. Como as informações de sessão usam cookies para a definir no cliente, através de um sessionid, este tem de ser definido nos cabeçalhos, e por isso não pode ser efectuado qualquer output.

Solução: Uma das soluções possíveis é garantir que não irá ocorrer nenhum output antes de ser enviado qualquer argumento na função header(). Alguns casos como exemplo:

echo "oi";
header("Location: outrapagina.php");

Neste excerto, a primeira linha pode ser descartada, uma vez que se o interesse é redireccionar para outrapagina.php, a mensagem, caso fosse possivel ter mostrá-la, não iria ser lida pelo cliente.

include("incluir.php");
header("Location: outrapagina.php");

À semelhança do código anterior, o ficheiro incluir.php poderá conter algum echo ou outra instrução que escreva para o browser.

Outra solução poderá ser activar o buffer que o PHP tem, para guardar todo o texto escrito nele, até pedirmos para o enviar para o browser. Vejamos o seguinte excerto de código:

// inciamos o buffer
ob_start();
echo "Menu: <a href="index.php?pag=comer">Comer</a> | <a href="index.php?pag=dormir">Dormir</a>";
 
// fazemos include da pagina pretendida
switch($_GET['pag']) {
case "comer":
	include("comida.php");
	break;
case "dormir":
	include("cama.php");
	break;
default:
	// dizemos a bots, etc, que a pagina nao existe
	header("404 Not Found");
}
 
// acaba aqui o nosso buffer
// Os headers que podiam ser enviados, já o foram
ob_flush();

Neste caso, queremos informar bots, por exemplos, de motores de busca, que se seguirem uma hiperligação que nao tenha uma pagina a incluir, lhes seja enviado o erro 404, para que saibam que essa página não existe, e para que não a registem. Como existe um caso em que os headers podem ser enviados (se não existir a tal pagina, por exemplo, o utilizador seguiu index.php?pag=estudar), o buffer deve ser activado como medida de precaução.

Outra situação muito comum também tem a ver com a codificação do ficheiro. Alguns editores de texto colocam os documentos com codificação UTF-8, com um byte inicial, chamado Byte Order Mark (BOM), que é interpretado como um conjunto de caracteres (frequentemente se encontram sequências como  no inicio de documentos, isto indica a presença do BOM). Para o remover, deve-se ter o cuidado de gravar o ficheiro em formato UTF-8 sem BOM.

Sessões

Problema: As sessões devolvem-me um erro, de headers already sent, como o resolver?

echo "oi";
session_start();

E retorna o erro:

Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at C:wampwwwprobs.php:1) in C:wampwwwprobs.php on line 2
 
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at C:wampwwwprobs.php:1) in C:wampwwwprobs.php on line 2

Basicamente, as mensagens são bastante explícitas. O erro prende-se com o problema do output e dos headers. Para iniciar uma sessão, é necessário colocar um cookie com o ID da sessão. Ora, o cookie com PHP terá de ser enviado nos headers e como tal, não poderá haver outputs.

Solução: A solução, igualmente simples, poderá passar por colocar o session_start no topo do ficheiro:

session_start();
echo "oi";

Como ver o conteúdo de um array?

$meuarray = array("bananas", "laranjas",5, array(2,"sementes"));
 
echo "<pre>";
print_r($meuarray);
echo "</pre>";

Para obter também informação acerca do tipo de dados, usar a função var_dump em vez da print_r. Esta função mostra tambem o conteúdo de objectos.

$meuarray = array("bananas", "laranjas",5, array(2,"sementes"));
var_dump($array);
 
$string = "oiasdfoaisfd";
var_dump($string);
 
$boolean = false;
var_dump($boolean);
 
$nulidades = NULL;
var_dump($nulidades);
 
class MyClass {
 function metodo() {
  return "olá";
 }
}
$m = new MyClass;
var_dump($m);
var_dump($m->metodo());

Posso misturar conteúdos HTML e PHP no mesmo ficheiro?

Sim, é possível colocar código HTML e PHP no mesmo ficheiro. Contudo, é necessário seguir algumas regras para que o ficheiro funcione:

  • Se o ficheiro contém código PHP, então o ficheiro deve ter a extensão php (por omissão)
  • O código PHP deve estar correctamente delimitado por <?php e ?>
  • Para escrever código HTML dentro do bloco de código PHP, deve-se usar uma função de escrita, tal como o echo

O seguinte exemplo demonstra PHP e HTML no mesmo ficheiro, a funcionar correctamente:

<html>
<body>
<h1>A minha web</h1>
<?php
  $paragrafo = "<p>E aqui esta o meu paragrafo gerado dinamicamente pelo PHP</p>";
?>
<p>Aqui esta um paragrafo ja escrito no documento</p>
<?php 
  echo $paragrafo;
?>
</body>
</html>

O texto da minha página tem caracteres esquisitos

Se a página apresentar caracteres esquisitos, normalmente quadrados com pontos de interrogação, ou outros caracteres no lugar dos acentuados, significa que está a ser assumido um encoding diferente do pretendido. Deve-se ter em atenção alguns aspectos:

  • O tipo de encoding da página deve ser definido no HTML ou nos cabeçalhos HTTP (exemplo são UTF-8, ISO-8859-15, etc)
  • Não é boa prática escrever palavras acentuadas directamente no código fonte. Devem ser usadas, em vez disso, html entities para os caracteres acentuados.

Uma forma rápida de resolver é indicar que a página está codificada em UTF-8, um padrão universal que abrange a maioria dos caracteres acentuados. Basta em PHP, antes de qualquer output, indicar a seguinte declaração:

header('Content-Type: text/html; charset=utf-8'); 
dev_web/php/problemas_comuns_em_php.txt · Esta página foi modificada pela última vez em: 2018/05/14 21:37 (Edição externa)