Hallo allemaal,

Ik heb met HTML5 (Bootstrap3) een contactformulier gemaakt.

Omdat ik de server taal PHP niet beheers ben ik opzoek gegaan naar een veilige code. Via w3schools.com kwam ik
een uitgebreid PHP script tegen voor formulieren.
https://www.w3schools.com/php/showphp.asp?filename=demo_form_validation_complete

Omdat ik het ingevulde formulier graag naar een e-mail adres wil laten sturen ben ik weer opzoek gegaan. Via phphulp.nl en PHPwiki heb ik stukjes code gevonden en vervolgens geprobeerd die stukjes script aan de code van w3schools.com toe te voegen. Klopt de code nu nog wel? Wellicht de volgorde?

Ik zie door de bomen het bos niet meer. Kan iemand mij alstublieft helpen?



<?php 
	
if(isset($_POST['emailadres'])) 
{
	$email_from = "[email protected]";
	$email_to = "[email protected]";
	$email_subject = "Contactform";
	
	$emailadres = filter_input(INPUT_POST,'emailadres', FILTER_VALIDATE_EMAIL);
	$naam = $_POST['naam'];
	$plaats = $_POST['plaats'];
	$email = $_POST['email'];
	$geslacht = $_POST['geslacht'];
	$comment = $_POST['comment'];
	$html = true;


$email_message = nl2br;

$headers .= "From:". $email_from . "\r\n";
$headers .= "To:". $email_to . "\r\n";
$headers .= "X-Mailer: PHP/".phpversion(). "\r\n";
$headers .= ($html) ? "MIME-Version: 1.0" . "\r\n";
$headers .= ($html) ? "Content-type:text/html;charset=UTF-8" . "\r\n";

@mail($email_to,$email_subject,$email_message,$headers);	
}
	
// define variables and set to empty values
$naamErr = $plaatsErr = $emailErr = $geslachtErr = $commentErr "";
$naam = $plaats = $email = $geslacht = $comment "";

if ($_SERVER["REQUEST_METHOD"] == "POST") {
  if (empty($_POST["naam"])) {
    $naamErr = "Typ uw naam in";
  } else {
    $naam = test_input($_POST["naam"]);
    // check if name only contains letters and whitespace
    if (!preg_match("/^[a-zA-Z ]*$/",$naam)) {
      $naamErr = "Alleen letters en spaties"; 
    }
  }
  
  if (empty($_POST["plaats"])) {
    $plaatsErr = "Typ uw woonplaats in";
  } else {
    $plaats = test_input($_POST["plaats"]);
    // check if name only contains letters and whitespace
    if (!preg_match("/^[a-zA-Z ]*$/",$plaats)) {
      $plaatsErr = "Alleen letters en spaties"; 
    }
  }
  
  
  if (empty($_POST["email"])) {
    $emailErr = "Typ geldig email adres";
  } else {
    $email = test_input($_POST["email"]);
    // check if e-mail address is well-formed
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
      $emailErr = "Ongeldige email"; 
    }
  }
    
	 if (empty($_POST["geslacht"])) {
    $geslachtErr = "Maak geslachts keuze";
  } else {
    $geslacht = test_input($_POST["geslacht"]);
  }
}
	
  if (empty($_POST["comment"])) {
    $comment = "Typ uw opmerking of vraag";
  } else {
    $comment = test_input($_POST["comment"]);
	// check if name only contains letters and whitespace
    if (!preg_match("/^[a-zA-Z ]*$/",$plaats)) {
      $plaatsErr = "Alleen letters en spaties"; 
  	}
  }


function test_input($data) {
  $data = trim($data);
  $data = stripslashes($data);
  $data = htmlspecialchars($data);
  return $data;
}
?>

	
<form class="form-horizontal" method="post" name="contactform" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">	
	
<h6>* Verplichte velden</h6><br />							
<div class="form-group row">
<label for="naam" class="col-sm-2 col-form-label">naam*</label>
<div class="col-sm-2">
<input class="form-control" type="text" name="naam" id="naam" placeholder="voor en achternaam" required>
<span class="error"><?php echo $naamErr;?></span>
</div>
</div>
				
<div class="form-group row">
<label for="plaats" class="col-sm-2 col-form-label">Woonplaats*</label>
<div class="col-sm-2">
<input class="form-control" type="text" name="plaats" id="plaats" required>
<span class="error"><?php echo $plaatsErr;?></span>
</div>
</div>
	
<div class="form-group row">
<label for="email" class="col-sm-2 col-form-label">E-mail*</label>
<div class="col-sm-3">
<input class="form-control" type="email" name="email" placeholder="[email protected]" id="email" required>
<span class="error"><?php echo $emailErr;?></span>
</div>
</div>
				
<div class="form-group row">
<label for="geslacht" class="col-sm-2">Geslacht*</label>
<div class="col-sm-2">
<select class="form-control" name="geslacht" id="geslacht">
<option>Man</option>
<option>Vrouw</option>
</select>
<span class="error"><?php echo $geslachtErr;?></span>
</div>
</div>
				
<div class="form-group row">
<label for="comment" class="col-sm-2">Opmerking*</label>
<div class="col-sm-5">
<textarea class="form-control" rows="3" name="comment" id="comment"></textarea>
<span class="error"><?php echo $commentErr;?></span>
</div> 
</div>	
				
<div class="form-group row">
<div class="col-sm-2"></div>
<div class="col-sm-2">
<button type="submit" class="btn btn-primary" value="sent">Verzend</button>	
</div>	
</div>	
</form>

<?php
echo "<h2>Your Input:</h2>";
echo $naam;
echo "<br />";
echo $plaats;
echo "br />"
echo $email;
echo "<br />";
echo $geslacht;
echo "<br />";
echo $comment;
echo "<br />";
?>

Nee, ik bedoel te zeggen, dat de mensen over het algemeen zelf heel goed weten hoe ze hun naam moeten schrijven.

In mijn naam komt geen J voor.
Dus stel dat ik daarom maar verbied om een "j" op te nemen in een naam.
Hoe ga jij je naam dan invoeren?

Dat is wat jij namelijk doet met "a-zA-Z "
Je staat een aantal tekens toe, en een hele boel niet. Waarom mogen Willem-Alexander en Máxima hun naam niet invoeren?

Ja, je kunt dit "oplossen" door en "a-zA-Zá -" te plaatsen in de regex. Maar dan komt Véronique langs. etc etc.

Daarom terug naar de vraag: wáárom verbied je die andere letters?
Het enige dat ik kan bedenken, is een beveiliging tegen XSS of SQL-injectie.
En daarvoor zijn prima andere oplossingen: htmlspecialchars() als je een naam op het scherm zet, of mysqli-real-escape-string() in je query.

Bij je controle functie hierboven zou ik hooguit controleren of de lengte van de naam groter is dan 0 tekens:
<?php if(strlen(trim($naam)) == 0) { // de naam was leeg, of bestond uit spaties } ?>

de functie htmlspecialchars() hoor je alleen te gebruiken in combinatie met "echo"
Goedemiddag iedereen,
De laatste tijd ben ik druk bezig geweest met het beveiligen van het formulier. Ik vraag me af of ik op de goede weg ben.

Bij de 2de 'if' van anti-flood worden er geen accolades gebruikt, maar zover ik weet hoort dit normaal gesproken wel. Waarom hier dan niet?



<?php 
session_start();		
if($_SERVER['REQUEST_METHOD']=="POST") {
	$email_from    = "[email protected]";
	$email_to      = "[email protected]";
	$email_subject = "Contactform";
	$vnaam         = $_POST['vnaam'];
	$anaam         = $_POST['anaam'];
	$plaats        = $_POST['plaats'];
	$email         = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
	$geslacht      = $_POST['geslacht'];
	$comment       = $_POST['comment'];
	$persoon       = filter_input(INPUT_POST, 'persoon', FILTER_VALIDATE_INT);
	$html	       = false;

	//anti-flood 30 sec. vertraging
	if (!empty($_SESSION['antiflood'])) {	
  }  $seconde = 30; 
     $tijd = time() - $_SESSION['antiflood'];
    if ($tijd < $seconde) 
     $antiflood = 1;
      // hier geen accolades?
	
	
$content     = 'Voornaam: ' . $vnaam ."\r\n" . 'Achternaam: ' . $anaam . "\r\n" . 'Plaats: ' . $plaats .    
                "\r\n" . 'E-mail: ' . $email . "\r\n" . 'Geslacht: ' . $geslacht . "\r\n" . 'Vraag: ' . $comment;

$headers    .= "From:". $email_from . "\r\n";
$headers    .= "X-Mailer: PHP/".phpversion(). "\r\n";
$headers    .= ($html) ? "MIME-Version: 1.0" . "\r\n" : '';
$headers    .= ($html) ? "Content-type:text/html;charset=UTF-8" . "\r\n" : '';
	
	
    if ($antiflood == "") 
  {  $_SESSION['antiflood'] = time();
	mail($email_to, $email_subject, $content, $headers);
     //Alles oke?
    header("location: bedankt.html");
    exit();
  } else  {
        echo "Er is een technische fout."; 
  }  
}
	
			

// define variables and set to empty values
$vnaamErr = $anaamErr = $plaatsErr = $emailErr = $geslachtErr = $commentErr = $persoonErr = "";
$vnaam    =	$anaam    = $plaats    = $email    = $geslacht    = $comment    = $persoon    = "";

			
if ("POST" == $_SERVER["REQUEST_METHOD"]) {
  if (empty($_POST["vnaam"])) {
    $vnaamErr = "Voornaam verplicht";
  } else {
    $vnaam = strip_tags(trim($_POST["vnaam"]));
    // niets ingevuld of bestond uit spaties
    if(strlen(trim($vnaam)) == 0) {  
		$vnaamErr = "Typ a.u.b. uw voornaam";
    }
  }
	

  if (empty($_POST["anaam"])) {
    $anaamErr = "Achternaam verplicht";
  } else {
    $anaam = strip_tags(trim($_POST["anaam"]));
    //  niets ingevuld of bestond uit spaties
    if(strlen(trim($anaam)) == 0) { 
		$anaamErr = "Typ a.u.b. uw achternaam";
    }
  }
	
  
  if (empty($_POST["plaats"])) {
    $plaatsErr = "Woonplaats verplicht";
  } else {
    $plaats = strip_tags(trim($_POST["plaats"]));
    // check if name only contains letters and whitespace
    if (strlen(trim($plaats)) ==0) {
      $plaatsErr = "Typ a.u.b. uw woonplaats"; 
    }
  }
  
  
  if (empty($_POST["email"])) {
    $emailErr = "E-mail adres verplicht";
  } else {
    $email = filter_var($email, FILTER_SANITIZE_EMAIL);
    // check if e-mail address is well-formed
    if (!filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
      $emailErr = "Ongeldige e-mail"; 
    }
  }
				
  
   if (empty($_POST["geslacht"])) {
    $geslachtErr = "Maak een keuze";
  } else {
    $geslacht = strip_tags(($_POST["geslacht"]));
  }
	
	
  if (empty($_POST["comment"])) {
    $commentErr = "Stel uw vraag";
  } else {
    $comment = htmlentities(trim($_POST["comment"]), ENT_NOQUOTES);
    // check of veld niet leeg is en max. 200 tekens bevat
    if (strlen($_POST['comment'])>= 1 && strlen($_POST['comment'])<=200) {
      $commentErr = "Typ uw vraag of opmerking, maximaal 200 tekens."; 
  	}
  }

	
  if (empty($_POST["persoon"])) {
	$persoonErr = "Geef een antwoordt op de vraag"; 
  } else {
	$persoon = intval($_POST["persoon"]);
	// Correct of fout antwoordt.
	if ($persoon !== 40) {
	$persoonErr = "Dat is helaas niet het goede antwoordt";	
	}  
  } 
?>

Indien er slechts één statement na een if of else volgt kunnen de accolades weggelaten worden. Dit bevorderd de leesbaarheid echter niet en vergroot de kans dat je fouten maakt.

dus

<?php
if ($tijd < $seconde)
$antiflood = 1;
?>

is het zelfde als

<?php
if ($tijd < $seconde) {
$antiflood = 1;
}
?>

Hm, maar wat doet die sluit-accolade aan het begin van regel 18? Ik vermoed dat ie ergens rond regel 43 moet komen (alleen verder als je überhaupt pas 'antiflood' in je $_SESSION hebt).
Zoals SanThe al aangaf: Gebruik een goede editor. Bijvoorbeeld Netbeans is gewoon gratis te downloaden. even je code in deze editor geplakt en alles geselecteerd en de code even geordend met [Alt]+[Shift]+[F] en het wordt al een stuk leesbaarder. Tabulaties (die een goede php editor weer omzet in een vast aantal spaties) zijn heel erg belangrijk. Zo laat je je code netjes inspringen en weet je of je in een lus dan wel een if zit of niet.

<?php

session_start();
if ($_SERVER['REQUEST_METHOD'] == "POST")
{
$email_from = "[email protected]";
$email_to = "[email protected]";
$email_subject = "Contactform";
$vnaam = $_POST['vnaam'];
$anaam = $_POST['anaam'];
$plaats = $_POST['plaats'];
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$geslacht = $_POST['geslacht'];
$comment = $_POST['comment'];
$persoon = filter_input(INPUT_POST, 'persoon', FILTER_VALIDATE_INT);
$html = false;

//anti-flood 30 sec. vertraging
if (!empty($_SESSION['antiflood']))
{
// EEN LEGE IF ???
}

$seconde = 30;
$tijd = time() - $_SESSION['antiflood'];
if ($tijd < $seconde)
$antiflood = 1;
// hier geen accolades?


$content = 'Voornaam: ' . $vnaam . "\r\n" . 'Achternaam: ' . $anaam . "\r\n" . 'Plaats: ' . $plaats .
"\r\n" . 'E-mail: ' . $email . "\r\n" . 'Geslacht: ' . $geslacht . "\r\n" . 'Vraag: ' . $comment;

$headers .= "From:" . $email_from . "\r\n";
$headers .= "X-Mailer: PHP/" . phpversion() . "\r\n";
$headers .= ($html) ? "MIME-Version: 1.0" . "\r\n" : '';
$headers .= ($html) ? "Content-type:text/html;charset=UTF-8" . "\r\n" : '';


if ($antiflood == "")
{
$_SESSION['antiflood'] = time();
mail($email_to, $email_subject, $content, $headers);
//Alles oke?
header("location: bedankt.html");
exit();
} else
{
echo "Er is een technische fout.";
}
}



// define variables and set to empty values
$vnaamErr = $anaamErr = $plaatsErr = $emailErr = $geslachtErr = $commentErr = $persoonErr = "";
$vnaam = $anaam = $plaats = $email = $geslacht = $comment = $persoon = "";


if ("POST" == $_SERVER["REQUEST_METHOD"])
{
if (empty($_POST["vnaam"]))
{
$vnaamErr = "Voornaam verplicht";
} else
{
$vnaam = strip_tags(trim($_POST["vnaam"]));
// niets ingevuld of bestond uit spaties
if (strlen(trim($vnaam)) == 0)
{
$vnaamErr = "Typ a.u.b. uw voornaam";
}
}


if (empty($_POST["anaam"]))
{
$anaamErr = "Achternaam verplicht";
} else
{
$anaam = strip_tags(trim($_POST["anaam"]));
// niets ingevuld of bestond uit spaties
if (strlen(trim($anaam)) == 0)
{
$anaamErr = "Typ a.u.b. uw achternaam";
}
}


if (empty($_POST["plaats"]))
{
$plaatsErr = "Woonplaats verplicht";
} else
{
$plaats = strip_tags(trim($_POST["plaats"]));
// check if name only contains letters and whitespace
if (strlen(trim($plaats)) == 0)
{
$plaatsErr = "Typ a.u.b. uw woonplaats";
}
}


if (empty($_POST["email"]))
{
$emailErr = "E-mail adres verplicht";
} else
{
$email = filter_var($email, FILTER_SANITIZE_EMAIL);
// check if e-mail address is well-formed
if (!filter_var($email, FILTER_VALIDATE_EMAIL) === false)
{
$emailErr = "Ongeldige e-mail";
}
}


if (empty($_POST["geslacht"]))
{
$geslachtErr = "Maak een keuze";
} else
{
$geslacht = strip_tags(($_POST["geslacht"]));
}


if (empty($_POST["comment"]))
{
$commentErr = "Stel uw vraag";
} else
{
$comment = htmlentities(trim($_POST["comment"]), ENT_NOQUOTES);
// check of veld niet leeg is en max. 200 tekens bevat
if (strlen($_POST['comment']) >= 1 && strlen($_POST['comment']) <= 200)
{
$commentErr = "Typ uw vraag of opmerking, maximaal 200 tekens.";
}
}


if (empty($_POST["persoon"]))
{
$persoonErr = "Geef een antwoordt op de vraag";
} else
{
$persoon = intval($_POST["persoon"]);
// Correct of fout antwoordt.
if ($persoon !== 40)
{
$persoonErr = "Dat is helaas niet het goede antwoordt";
}
}
?>

[size=xsmall]Toevoeging op 20/02/2018 20:32:13:[/size]

Behalve die accolade sluiten van Rob mis je onderin ook nog een accolade sluiten.
Waarom twee keer controleren of de request methode 'POST' is?
Dankjewel voor je advies Frank.

Ik heb Netbeans ondertussen in gebruik genomen, handig programma.

Daarnaast ben ik een boek over PHP aan het lezen: PHP7 in easy steps.
Na dit boek wil ik me gaan verdiepen in OOP (Object Oriented PHP).
Zodat ik een PHP framework kan gebruiken.
Mooie goals :-)

Veel plezier met programmeren!

Reageren