Header (location: ) werkt niet
Om midden in een script naar een ander bestand te gaan maak ik gebruik van header (location:xxx.php). Op mijn lokale server geeft het geen problemen, maar na de boel geupload te hebben werkt dat niet meer. Ik heb gelezen dat vóór de header geen output mag zijn. Maar waarom werkt het dan wel op mijn eigen server? Zijn er misschien andere (betere) oplossingen hiervoor?
B-O-M zijn.
Zet foutafhandeling in PHP eens aan, en kijk eens wat voor fouten je zien omtrent je header. De foutmelding verwijst ook naar de plek waar de output zich bevindt, met de regel na de dubbele-punt.
Het enige wat ik mij kan bedenken waarom het op de andere server niet zou werken is dat er toch ergens output voor staat. Het kan zelfs al een onschuldige Zet foutafhandeling in PHP eens aan, en kijk eens wat voor fouten je zien omtrent je header. De foutmelding verwijst ook naar de plek waar de output zich bevindt, met de regel na de dubbele-punt.
De enigste juiste oplossing is je code zo op te bouwen dat je het splitst in twee gedeeltes:
Deel 1: je applicatie waarin je variabelen "klaar zet" voor de view (=deel 2). In dit deel doe je geen enkele output BEHALVE een fatal error waarna je applicatie dan ook direct stopt (exit;).
Deel 2: je view waarin je enkel HTML gebruikt en hele kleine blokjes PHP niet meer dan noodzakelijk en enkel om je variabelen te echoën al dan niet in een foreach lus.
Gewijzigd op 01/05/2017 14:32:05 door Frank Nietbelangrijk
Er staat idd output voor. Dat zal dan ook wel zeer waarschijnlijk de oorzaak zijn. Maar wat ik vreemd vind is dat het mijn eigen server wel werkt. Ik zou het wel kunnen oplossen dmv bijvoorbeeld een 'tussenscherm' zodat je van daaruit naar de betreffende pagina kunt (dus zonder gebruik te maken van de header), maar dat geniet bij mij niet de voorkeur. Frank: bedoel je dan ook om de query in een variabele te plaatsen?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
// DEEL 1: De Applicatie
// initialisatie van de variabelen
$users = array();
// maak verbinding met de mysql server
$con = mysqli_connect('','','','');
// verkrijg een lijst met gebruikers
$result = mysqli_query($con, 'SELECT name FROM users');
if(FALSE === $result) {
echo 'FOUT: blablabla';
exit;
}
while($row = mysqli_fetch_assoc($result)) {
$users[] = $row;
}
// Hieronder komt DEEL 2: De View:
?>
<!doctype>
<html>
<body>
<h1>User list</h1>
<ul>
<?php foreach($users as $user) { ?>
<li><?php echo $user['name']; ?></li>
<?php } ?>
</ul>
</body>
</html>
// DEEL 1: De Applicatie
// initialisatie van de variabelen
$users = array();
// maak verbinding met de mysql server
$con = mysqli_connect('','','','');
// verkrijg een lijst met gebruikers
$result = mysqli_query($con, 'SELECT name FROM users');
if(FALSE === $result) {
echo 'FOUT: blablabla';
exit;
}
while($row = mysqli_fetch_assoc($result)) {
$users[] = $row;
}
// Hieronder komt DEEL 2: De View:
?>
<!doctype>
<html>
<body>
<h1>User list</h1>
<ul>
<?php foreach($users as $user) { ?>
<li><?php echo $user['name']; ?></li>
<?php } ?>
</ul>
</body>
</html>
Toevoeging op 01/05/2017 15:13:46:
In een beetje verder ontwikkeld systeem zullen de applicatie en de view ook in twee afzonderlijke bestanden staan. Een volgende stap is om ook je queries in een aparte class-methods te zetten waarna je vanuit je Applicatie gewoon een functie aanroep doet. Maar goed al begin je maar met het bovenstaande dan komt er al een stuk meer structuur je in code.
Beste Frank en Ariën, bedankt voor de reacties. Ik zal het toch op een andere manier moeten fixen. Dus zonder header helass. Het heeft idd te maken met de output.
Met de headers zelf is niks mis, dus waarom zou je daar vanaf stappen?
Gewijzigd op 01/05/2017 19:18:13 door Ton Dekkers
Zet je error-reporting eens aan. Ik vermoed dan dat je een foutmelding over je headers krijgt?
Nog steeds helemaal blanco.....
Frank Nietbelangrijk op 01/05/2017 14:26:06:
De enigste juiste oplossing is je code zo op te bouwen dat je het splitst in twee gedeeltes
Nou nee, niet per se.
Je zou je code ook kunnen laten draaien om / kunnen compartimenteren in acties. Deze acties bepalen op hun beurt of en wat voor output (lees: Content-Type) er geproduceerd moet worden. Op die manier heb je altijd de controle over wat voor output er gegenereerd wordt. De uit te voeren actie zou bijvoorbeeld tot uiting kunnen komen door een querystring-variabele: ?action=...
Denk bij acties bijvoorbeeld aan:
- een actie om een formulier weer te geven (myform.php?action=showForm). Dit zou dan moeten resulteren in het renderen van een HTML-pagina (een maintemplate met een formulier); het action-attribuut verwijst hierbij naar de URL om het formulier te verwerken (zie hieronder)
- een actie om een formulier te valideren en te verwerken (myform.php?action=processForm). Dit is enkel code die verder geen output produceert maar een die je direct doorstuurt naar een andere actie, bijvoorbeeld een bedank-boodschap (wederom een HTML-pagina; myform.php?action=thankYou) indien de invoer correct was of dat je teruggestuurd wordt naar de toon-formulier-actie met een foutmelding indien de invoer niet klopte (myform.php?action=showForm&error=1).
- een actie om een JSON-response te genereren waarmee je een dynamische dropdown vult in de eerdergenoemde formulier-actie (myform.php?action=JSONfillDropdown¶m=123)
et cetera
NB als je geen errors ziet, zet dit bovenaan je script:
Code (php)
1
2
3
4
2
3
4
<?php
ini_set('display_errors', 'stdout'); // geeft aan waar foutmeldingen worden gemeld
error_reporting(E_ALL); // geeft aan welke foutmeldingen worden gemeld
?>
ini_set('display_errors', 'stdout'); // geeft aan waar foutmeldingen worden gemeld
error_reporting(E_ALL); // geeft aan welke foutmeldingen worden gemeld
?>
En/of controleer de netwerk-tab van je browser. Als je HTTP 500 errors (internal server errors) krijgt zou je ook je errorlogs kunnen (downloaden en) raadplegen.
Gewijzigd op 01/05/2017 22:28:37 door Thomas van den Heuvel
Ik krijg nu de foutmeldingen wel door. Ik dacht dat 'error_reporting(E_ALL)' voldoende was ;). Bedoel je het gebruik maken van 'switch' Thomas?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
De eerste 'headerfout' was opgelost en de tweede diende zich al weer aan. Ik dacht ook dat een switch handig zou zijn, doch had ik nog wat div's boven de switch staan voor de opmaak. Zeer waarschijnlijk dat dat de boosdoeners zijn geweest. Ik plaats dit item nu in een apart bestand en daarmee is het probleem ook opgelost. In de eerste instantie had ik het graag binnen de index.php gehouden dmv een switch. Graag wil ik jullie allemaal bedanken voor de hulp.
Een bron van dit soort fouten:
staat op je productieserver de buffer uit, of lager heb je een fout te pakken.
staat de buffer kantje boort, dan gaat het altijd goed met de username 'test' en het adres 'plein 1' in beeld, maar gaat het fout als de user 'willem-alexander van Oranje nassau' heet en op de 'Laan van Meerdevoorden 1209' woont, omdat je dan net over je header heen gaat.
In zijn simpelste vorm zou ik opteren voor een "paginatype" klasse die als een raamwerk dient voor eigenlijk alle (vervolg)pagina's (die hiervan afgeleid zijn) die een dynamisch karakter hebben. Maar dit is wederom een keuze. In plaats van methoden die elk een specifieke actie implementeren zou je ook kunnen kiezen voor een apart PHP-bestand voor elke specifieke taak. Welke oplossing je kiest is afhankelijk van persoonlijke voorkeur, niveau en complexiteit van je applicatie. De onderliggende aanpak (behandel maximaal één actie tegelijkertijd) blijft echter hetzelfde.