wiki.phpfreakz.nl
Aanmelden Artikel Overleg Bewerk Geschiedenis Go to the site toolbox

Headers Already Sent

Inhoud

Wat is de foutmelding?

Dit artikel gaat over de veel voorkomende foutmelding:

Warning: Cannot add header information - headers already sent by (output started at index.php:3) in index.php on line 1 


Veel mensen op het forum vragen zich af wat deze foutmelding betekent en hoe ze hem kunnen oplossen. In dit artikel zal ik de verschillende aspecten van de foutmelding behandelen en proberen een oplossing te vinden.

Wat zegt de foutmelding?

De foutmelding zegt dat er output is geweest voor een bepaalde lijn. Op die lijn staat meestal een van deze functies:

Setcookie() Header() Session_start()

Een voorbeeld van een fout script kan zijn:

<?php
echo "He, jij hoort hier niet, ik ga je nu redirecten!";
header("Location: http://domein.nl/redirect.html");
?>

Onduidelijker kan ook, je kunt bijvoorbeeld per ongeluk een spatie of enter voor je php code hebben staan. Dit valt nauwelijks op, maar php ziet dit wel als output.

  1. <?php
  2. ?>

In beide gevallen hebben we iets naar de browser gestuurd voordat we nog iets aan de headers willen veranderen. 3) Waardoor krijg ik de foutmelding? Via een web browser werk je met het protocol HTTP (Hypertext Transfer Protocol). Hierin is vastgelegd hoe een pagina aanroep eruit moet zien en welke gegevens een browser terugkrijgt voor het weergeven van een bepaalde pagina. Een voorbeeld van het opvragen van een pagina kan er zo uitzien:

GET /index.php HTTP/1.1
Host: phpfreakz.nl

Als reactie op deze request krijg je een response terug, die er als volgt uit kan zien:

HTTP/1.1 200 OK
Connection close
Date: Thu, 06 Aug 1998 12:00:15 GMT
Server: Apache/1.3.0 (Unix)
Last-Modified: Mon, 22 Jun 1998
Content-Length: 6821
Content-Type: text/html

<html>
<head>
<title>Pagina</title> 
...

Via de bovenstaande functies wil je gegevens aanpassen in de headers van de response. Je kunt bijvoorbeeld instellen hoe je wilt cachen of een locatie aangeven waar de pagina heen verwijst. De opbouw van een HTTP response vertelt ons dat na de headers een carriage return moet komen, waarna de eigenlijke inhoud van de pagina komt. Als je eerst een stukje tekst stuurt, sluit PHP de headers van de HTTP response af, doormiddel van een carriage return en stuurt deze alvast naar de browser. Daarna begint PHP met het sturen van de body van de response, veelal de HTML dus. Als jij daarna weer headers wilt toevoegen krijg je een foutmelding, want hij heeft het gedeelte voor de headers al afgesloten en verzonden. PHP zegt heel duidelijk wat er aan de hand is, namelijk:

Warning: Cannot add header information - headers already sent by (output started at index.php:1) in index.php on line 3 

Vertalen naar het Nederlands levert op:

Waarschuwing: Kan geen header informatie toevoegen - headers zijn al verzonden (output gestart op index.php:1) in index.php op regel 3 

Tussen de haakjes geeft hij zelfs al aan waar je je output hebt staan, heel simpel om dat terug te vinden en op te lossen dus.

Hoe kan ik de foutmelding weg krijgen?

Er zijn 2 mogelijke oplossingen voor het probleem. De beste oplossing is ervoor zorgen dat je geen gegevens verzendt voordat je de bovenstaande functies aanroept. Bij het scripten moet je er dus rekening mee houden dat die functies altijd als eerste behandeld worden, daarna komt de rest pas. Het zijn de zaken die je als eerste moet weten, daarna komt de rest van de pagina inhoud pas. Een kleine moeite en het voorkomt een foutmelding. Voorbeeld:

<?php
session_start();
echo "En nu pas de teksten";
?>

Mogelijkheid twee is output buffering. Via output control kan je de output naar de browser vasthouden totdat je een bepaald commando geeft. Je kunt dan je hele script door de headers aanpassen zonder foutmeldingen te krijgen. Aan het einde stuur je alle inhoud van de buffer in een keer. Voorbeeld:

<?php
ob_start();
echo "Een stukje tekst";
 
setcookie("cookiename", "cookiedata");
 
ob_end_flush();
?>

Output buffering is eigenlijk meer het probleem omzeilen dan het eigenlijk oplossen. Het is dus zeker aan te raden om tijdens het scripten de eerste oplossing te gebruiken.

Let er overigens op, dat in php.ini de regels

output_buffering = On
output_buffering = 2048

kunnen staan. Daarmee buffert php dus al automatisch de output tot de limiet (2048) bereikt wordt. Lijkt handig, omdat je dat de headers-already-sent error omzeilt. Vervelende bijkomstigheid is, dat een script dan onvoorspelbaar gedrag gaat vertonen: op de ene server gaat het goed, terwijl een andere server die de output buffering uit heeft staan, een foutmelding geeft.

Bovendien heb je kans dat een script goed werkt als iemand op het adres "Plein 1" woont en het misgaat als het adres "Laan van Meerdervoort 1000" is, omdat de limiet overschreden wordt. Kies op je ontwikkelomgeving dus voor

output_buffering = Off

BOM (Byte Order Mark)

In sommige gevallen bestaat de foutmelding nog steeds ondanks dat de bovenstaande oplossingen zijn toegepast. In dit geval kan het komen doordat de pagina's opgeslagen zijn als UTF-8 mèt BOM. Dit is te herkennen aan 3 tekentjes aan het begin van de pagina:



Verander de instellingen van de editor, zodat de bestanden worden opgeslagen als UTF-8 zonder BOM en sla de pagina's opnieuw op.

Zie ook: Charactersets#UTF-8_in_bestanden


Ik hoop dat ik op deze manier voldoende informatie gegeven heb over dit onderwerp en dat iedereen lang zonder deze foutmelding mag scripten!

Site Toolbox:

Persoonlijke hulpmiddelen
De laatste wijziging op deze pagina vond plaats op 23 mrt 2010 11:27. - Deze pagina werd 9.932 maal bekeken. - Disclaimers - Over PFZWIKI