Hallo,

Ik heb een contactformulier waarin de afhandeling en het formulier in hetzelfde PHP bestand zitten. Ik gebruik POST variabelen.


Nu heb ik last van het bekende probleem dat na verzending het formulier opnieuw verzonden wordt als ik de pagina ververs. Voor zover ik weet is het niet mogelijk om de POST variabelen leeg te maken direct na verzending, omdat ze nog in het geheugen van de browser zitten.

Heeft iemand hier een idee wat te doen om dit probleem te voorkomen?

Guido
Een sessie hoeft niet, zoals ik al zei.
Want alles zit nog in je $_POST. Tenzij je een location-header gebruikt.

Persoonlijk raad ik aan om alles in een bestand af te handelen. Als je wilt zal ik straks even een opzetje maken.
Een opzetje voor me maken vind ik sowieso niet erg ;-)

Het gaat mij er dus om hoe ik ná de afhandeling weer terug ga naar form.php en daar mijn foutmelding toon, en dus zonder gebruik te maken van de header location.

Maar als jij een voorbeeld hebt om alles toch in hetzelfde bestand af te handelen (en mét oplossing van de pagina verversing), ik ben benieuwd.
Hier voorbeeld om werking van JS te zien :

<?php
if ( $_REQUEST["submit"] ) {
	// alles afhandelen
	echo "<pre>";
	print_r($_POST);
	echo "</pre>";
}
?>
<html>

<head>

<script>
if ( window.history.replaceState ) {
	// haal comment volgende regel weg om het effect te zien van een herlaad pagina
	//window.history.replaceState( null, null, window.location.href );
}
</script>

</head>

<body>

<form method="POST">
	<input type="text" name="tekst">
	<input type="submit" name="submit" value="submit">
</form>
	
</body>

</html>


Is allemaal te vinden op de interwebs.
Maar JavaScript is niet alles. Je zult het ook serverside moeten oplossen met een redirect in PHP.
Je kan in website prima met $_GET een aparte actie maken waarheen je doorgestuurd wordt als alles goed is gegaan.
Even voor de duidelijkheid, de "header location" alleen gebruiken in het geval van een succesvolle verzending. Nooit de terugmelding van de foutieve input via "header location" doen, omdat je dan alle (foutieve) input weer kwijt bent en het formulier opnieuw kunt invullen. Correct?

Ja en nee. Omdat je de acties splitst heb je dus nu een middel nodig om informatie over te hevelen. Een actie die "geen output produceert" zoals de verwerkstap van een formulier zal iemand altijd op een of andere manier doorsturen. Dit is juist de crux van POST/redirect/GET, zodat je nooit meer terug kunt naar de POST-stap. Dit kan dus ook inhouden dat je de foutieve informatie (middels een sessie) onthoudt en de gebruiker terugstuurt naar een formulier. Een alternatieve manier is dat je het formulier submit via AJAX, in welk geval je de pagina niet (geheel) verlaat (EDIT: maar ook daar zul je maatregelen moeten treffen om dubbelposts tegen te gaan).

Het gaat mij er dus om hoe ik ná de afhandeling weer terug ga naar form.php en daar mijn foutmelding toon, en dus zonder gebruik te maken van de header location.

In de verwerkstap wordt besloten waar je naartoe wordt (terug)gestuurd. Hoe je vervolgens je data over meerdere pagina's vasthoudt is een apart probleem dat je dus ook apart zult moeten oplossen. Zoals aangegeven maakt het "redirect" deel uit van de oplossing, ook als je teruggaat naar het formulier. In deze opzet heb je gewoon altijd headers nodig, en dat introduceert de noodzaak om op een of andere manier de invoer te "redden" zodat deze weer teruggeplaatst kan worden in het formulier. De enige (?) manier om dit zonder headers te doen is via AJAX je formuliersubmits afhandelen.

Niemand heeft ooit gezegd dat een gestructureerde oplossing makkelijker zou zijn, maar als je meer/heel veel met pagina's met deze opzet werkt, dan heb je deze extra administratie zo terugverdiend.

EDIT: wat ontbreekt in het zeer korte artikel waar je eerder naar linkte was nagaan of er inderdaad sprake is van een form submit, en ook een validatie van de velden met op zijn minst een controle op het bestaan hiervan. Heb je het artikel waar ik naar linkte ook gelezen?
Hoi,

Ik heb het artikel wel gelezen maar het werd op den duur te complex voor mij.

Misschien is de meest eenvoudige oplossing om toch te werken met een sessie om de input waarden te onthouden.

Dit is een werkend voorbeeld geworden (typfout voorbehouden) bestaande uit het formulier (form.php) en afhandeling (validate.php) en dus volgens het POST/redirect/GET patroon.

Form.php:

<?php
// Start sessie
if (!isset ($_SESSION)) session_start(); 
?>
<html>
<body>
<head>
</head>
<body>
<div>
	// Toon resultaat
	<?php
	$check = $_GET['m'];
	if ($check == error) {
		echo 'Fout bericht';
	}
	if ($check == success) {
		unset($_SESSION['name']);
		echo 'Succes bericht';
	}
	?>
	// formulier	
	<form action="validate.php" method="POST">
		<label>Naam:</label>
		<input name="name" type="text" value="<?php echo $_SESSION['name'] ?>" > 
		<input type="submit" value="Versturen" >
	</form>
</div>
</html>
</body>


Validate.php:

<?php
// Start sessie 
if (!isset ($_SESSION)) session_start(); 

// Formulier afhandeling
if($_SERVER['REQUEST_METHOD'] == 'POST') {
	// Variabelen
	$name = strip_tags($_POST['name']);

	// Sessie variabelen
	$_SESSION['name'] = $name; 

	// Valideer invoer 
	if( empty($name) ) {
		// Fout
		header("location:form.php?m=error");
	} else {
		// verstuur bericht enzo

		// Succes
		header("location:form.php?m=success");
	}
}
?>


Graag je reactie.

Guido
Vergeet de exit() niet na de location-header, je script moet ook stoppen.
Verder ozu ik je strip_tags() uitvoeren op het moment dat je de inhoud ophaalt, i.p.v. dat je het erin plaatst. Zorg dat deze altijd rauw is.

En waarom in twee bestanden? Je kan toch prima in één bestand werken? Veel overzichtelijker :-)
Dank voor je reactie.

Wat je laatste opmerking betreft, daar zijn overduidelijk de meningen over verdeeld ;-)

Guido
Hiero,

<?php
if( $_SERVER['REQUEST_METHOD'] == 'POST') {
	$name = strip_tags($_POST['name']);
    if( empty( $name ) ) {
		$m = "error";
	} else {
		$m = "success";
    }
}
?>
<html>
<body>
<head>
<script>
if ( window.history.replaceState ) {
	//haal comment volgende regel weg om het effect te zien van een herlaad pagina
	window.history.replaceState( null, null, window.location.href );
}
</script>
</head>
<body>
<div>

<?php
if ( $m == "error" ) {
	echo '<p>Fout bericht</p>';
} elseif ($m == "success") {
	echo '<p>Succes bericht</p>';
}
?>

<form method="POST">
	<label>Naam:</label>
	<input name="name" type="text" autofocus value="<?php echo $name; ?>" > 
	<input type="submit" value="Versturen" >
</form>

</div>

</html>

</body>
Nu nog wel, maar uiteindelijk wordt je applicatie steeds lastiger te doorgronden als je alles in aparte bestanden plaatst, zonder dat je weet of waar en of er samenhang is tussen bestanden.

Reageren