Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[PHP] foutafhandeling in contactformulier

Pagina: 1
Acties:

Onderwerpen


  • mr_fragle
  • Registratie: Oktober 2000
  • Laatst online: 12:46

mr_fragle

Don't forget the guide

Topicstarter
Ik ben bezig met een simpele website met een contactformulier. Heb in een ver verleden (8 jaar terug) wat vaker met ASP gewerkt. Server waar de website op komt draait echter alleen PHP, en dat lukt me maar met moeite. Inmiddels wel een random background in php werkend. Contactformulier met foutcontrole werkt eigenlijk prima, en komt ook nog aan :) Heb een op het web ronddwalend voorbeeld gebruikt.

Ik heb werkende foutcontrole op alle velden werkend. Inmiddels ook zover dat de velden e-mail en telefoonnummer niet alletwee hoeven worden ingevuld (of/of is dus voldoende).

Het enige dat ik nog zou willen is dat de bedrijfsnaam niet vereist is, maar dat als de bedrijfsnaam is ingevuld, dat dan ook alleen de door mij gespecificeerde tekens daarin mogen voorkomen.


code:
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
    <?php
if(isset($_POST['email'])) {
     
    
    $email_to = "naam@mailadres.nl";
    $email_subject = "contactgegevens"; //onderwerp van email
     
     
    function died($error) {
        
        echo "Het spijt ons, maar er is iets misgegaan.<br />";
        echo "Het volgende ging fout:<br /><br />";
        echo $error."<br /><br />";
        echo "Ga een pagina terug om deze fouten te herstellen.<br />";
        echo "Mocht het verzenden van het formulier onverhoopt niet werken, neem dan telefonisch contact met mij op via telefoonnummer.
        <br /><br />";
        die();
    }
     
    // Controle of verplichte velden niet leeg zijn
    if(
        !isset($_POST['bedrijfsnaam']) ||                                   //niet verplicht
        !isset($_POST['contactpersoon']) ||                                 //niet verplicht
        (!isset($_POST['email']) & !isset($_POST['telefoonnummer'])) ||     //een van de twee is verplicht
        !isset($_POST['opmerking']))                                        //verplicht
            {
            died('Het spijt me, maar het lijkt erop dat er iets fout gaat. <br /> Neem contact met mijop via telefoonnummer.');       
            }
     
    $bedrijfsnaam = $_POST['bedrijfsnaam'];         // niet verplicht
    $contactpersoon = $_POST['contactpersoon'];     // verplicht
    $email = $_POST['email'];                       // verplicht tenzij telefoonnummer is ingevuld
    $telefoonnummer = $_POST['telefoonnummer'];     // verplicht tenzij email is ingevuld
    $opmerking = $_POST['opmerking'];               // verplicht
    
    //onderstaand de foutafhandeling indien velden met onjuiste tekens worden ingevuld
     
    $error_message = "";
    $email_exp = '/^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/';
    $string_exp = "/^[0-9 -]+$/";
  if((!preg_match($email_exp,$email)) & (!preg_match($string_exp,$telefoonnummer))) {
    $error_message .= 'U dient een geldig telefoonnumer of e-mail adres in te vullen.<br />';
  }
//        $string_exp = "/^[0-9 -]+$/"; //foutafhandeling voor alleen telefoonnummer
//  if(!preg_match($string_exp,$telefoonnummer)) {
//  $error_message .= 'Het ingevoerde telefoonnummer is ongeldig.<br />';
//  }
  
    $string_exp = "/^[A-Za-z .'-]+$/";
  if(!preg_match($string_exp,$bedrijfsnaam)) {
    $error_message .= 'De ingevoerde bedrijfsnaam is ongeldig.<br />';
  }
  if(!preg_match($string_exp,$contactpersoon)) {
    $error_message .= 'De ingevoerde contactpersoon is ongeldig.<br />';
  }
  if(strlen($opmerking) < 2) {
    $error_message .= 'De ingevoerde opmerking/vraag is ongeldig.<br />';
  }
  
  if(strlen($error_message) > 0) {
    died($error_message);
  }

    $email_message = "contactgegevens:\n\n"; 
     
    function clean_string($string) {
      $bad = array("content-type","bcc:","to:","cc:","href");
      return str_replace($bad,"",$string);
    }
     
    $email_message .= "Bedrijfsnaam: ".clean_string($bedrijfsnaam)."\n";
    $email_message .= "Contactpersoon: ".clean_string($contactpersoon)."\n";
    $email_message .= "Email: ".clean_string($email)."\n";
    $email_message .= "Telefoonnummer: ".clean_string($telefoonnummer)."\n";
    $email_message .= "Opmerking: ".clean_string($opmerking)."\n";
     
     
// aanmaken email headers
$headers = 'From: '.$email."\r\n".
'Reply-To: '.$email."\r\n" .
'X-Mailer: PHP/' . phpversion();
@mail($email_to, $email_subject, $email_message, $headers);  
?>
 
<!-- hieronder de melding bij correcte verzending -->
 
Bedankt voor het invullen van het formulier, we nemen snel contact met u op. Klik hier om terug te gaan naar onze site. 
 
<?php
}
?>


Heeft er misschien mee te maken dat ik niet precies snap wat de volgende code doet:
code:
1
2
3
4
5
6
7
8
9
    // Controle of verplichte velden niet leeg zijn
    if(
        !isset($_POST['bedrijfsnaam']) ||                                   //niet verplicht
        !isset($_POST['contactpersoon']) ||                                 //niet verplicht
        (!isset($_POST['email']) & !isset($_POST['telefoonnummer'])) ||     //een van de twee is verplicht
        !isset($_POST['opmerking']))                                        //verplicht
            {
            died('Het spijt me, maar het lijkt erop dat er iets fout gaat. <br /> Neem contact met mij op via telefoonnummer.');       
            }


Als ik het logisch lees zou dat laatste blok ervoor moeten zorgen dat het altijd fout gaat indien ik 1 veld niet invul?

Ik hoop dat iemand een toelichting kan geven. Heeft al een behoorlijke tijd geduurd om uberhaubt een contactformulier te krijgen dat ook nog een e-mail wil verzenden. Laatste puntje op de i kom ik echter niet meer uit (kan ook tijdstip zijn;) )

And now the most interresting part of deze grot


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:08
Dit heeft eigenlijk weinig met PHP te maken, maar meer met basale programmeerskills. Maar om het even toe te lichten:

[list]
• isset() is een functie welke een boolean (true/false) teruggeeft met of een variabele gevuld is en dus niet NULL is.
• ! is een ontkenning, dus wanneer isset() false teruggeeft én wanneer er een ! voorstaat, is dat dus waar.
• $_POST[] is een algemene (magic) array met post waardes, welke worden meegegeven met de HTML-post
• & is een bitwise and. Die controleert of bitwise twee (of meer) variabelen gelijk zijn, zo ja krijg je true terug, anders false.
• || is een OF.


In jouw twee code excerpt is zowel de bedrijfsnaam, als de contactpersoon, als OF het email OF het telefoonnummer of de opmerking verplicht. Dus wanneer één van de variabelen niet-leeg is, krijg je true (waar) terug en overlijd het formulier.

Wat jij eerder zoekt is een && (AND) :). Dan hoef je ook niet per se te controleren op bedrijfsnaam of contactpersoon. Let daarnaast ook op, op XSS. Daar is je script nu namelijk gevoelig voor :).

  • mr_fragle
  • Registratie: Oktober 2000
  • Laatst online: 12:46

mr_fragle

Don't forget the guide

Topicstarter
Ok, waarschijnlijk inderdaad wat basaal, maar het is erg lang geleden voor mij. Excuses daarvoor

Ik merk inderdaad dat alleen een enkele & niet doet wat ik wel, en een dubbel && wel (ik was ook opzoek naar de AND in php, & leek mij wel logisch nadat ik erachter kwam dat AND niet werkt). Inmiddels werkt mijn formulier naar behoren.

Ik had inderdaad begrepen dat !(isset) een boolean teruggeeft. Is het dan zo dat onderstaand deel van de code alleen checkt of er uberhaubt waardes uit mijn contact.html binnenkomen in mijn php en dus niet of deze lees zijn?

code:
1
2
3
4
5
6
7
8
9
    if(
        !isset($_POST['bedrijfsnaam']) ||                               
        !isset($_POST['contactpersoon']) ||                             
        !isset($_POST['email']) ||
        !isset($_POST['telefoonnummer']) ||                                 
        !isset($_POST['opmerking']))                                        
            {
            died('Het spijt ons, maar het lijkt erop dat er iets fout gaat. <br /> Neem contact met ons op via telefoonnummer.');       
            }


XSS is te voorkomen dvm htmlspecialchars lijkt me:
code:
1
$bedrijfsnaam = htmlspecialchars($_POST['bedrijfsnaam']);


In ieder geval bedankt!

[ Voor 6% gewijzigd door mr_fragle op 15-11-2011 00:08 . Reden: xss ]

And now the most interresting part of deze grot


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:08
Bijna goed :). Om je een duwtje in de rug te geven:

PHP:
1
2
3
4
5
6
7
if(
        !isset($_POST['bedrijfsnaam']) && !isset($_POST['contactpersoon']) &&                              
        ( !isset($_POST['email']) || !isset($_POST['telefoonnummer']) ) &&
        !isset($_POST['opmerking']))                                          
            {
            died('Het spijt ons, maar het lijkt erop dat er iets fout gaat. <br /> Neem contact met ons op via telefoonnummer.');       
            }

Alles verplicht behalve email en telefoonnummer. Hiervan moet wel één van beide ingevuld zijn. Als ik het zo goed heb, ook kijkend naar de klok :). Heb je er anders moeite mee, hak de if dan op in meerdere kleine if's, combineren kan later altijd weer :).

  • AW_Bos
  • Registratie: April 2002
  • Nu online

AW_Bos

Liefhebber van nostalgie... 🕰️

let er wel even op die die() (wat je in je died() functie gebruikt niet echt logisch is. en script hoort juist niet te stoppen als er een validatie-fout plaatsvind. HTML wordt dan ook direct afgebroken waardoor je pagina niet voldoet aan de W3-validatie.

Telecommunicatie van vroeger
🚅Alles over spoor en treintjes


  • koendenb
  • Registratie: Januari 2011
  • Laatst online: 19:15
AW_Bos schreef op dinsdag 15 november 2011 @ 15:36:
let er wel even op die die() (wat je in je died() functie gebruikt niet echt logisch is. en script hoort juist niet te stoppen als er een validatie-fout plaatsvind. HTML wordt dan ook direct afgebroken waardoor je pagina niet voldoet aan de W3-validatie.
Precies zoals hier boven wordt verteld ja, je kan het daarom beter zo oplossen:

PHP:
1
2
3
4
5
6
7
8
9
10
   !isset($_POST['bedrijfsnaam']) && !isset($_POST['contactpersoon']) &&                               
   ( !isset($_POST['email']) || !isset($_POST['telefoonnummer']) ) && 
   !isset($_POST['opmerking']))                                           
   {
      echo'Het spijt ons, maar het lijkt erop dat er iets fout gaat. <br /> Neem contact met ons op via telefoonnummer.';        
   }
   else
   {
      //Wat hij moet doen als alles in orde is
   }


De error die je geeft is overigens ook een beetje raar, er gaat niets fout hij is gewoon iets vergeten.

[ Voor 9% gewijzigd door koendenb op 15-11-2011 16:20 ]


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:08
koendenbraven schreef op dinsdag 15 november 2011 @ 16:19:
[...]


Precies zoals hier boven wordt verteld ja, je kan het daarom beter zo oplossen:

PHP:
1
2
3
4
5
6
7
8
9
10
   if (!isset($_POST['bedrijfsnaam']) && !isset($_POST['contactpersoon']) &&                               
   ( !isset($_POST['email']) || !isset($_POST['telefoonnummer']) ) && 
   !isset($_POST['opmerking']))                                           
   {
      echo'Het spijt ons, maar het lijkt erop dat er iets fout gaat. <br /> Neem contact met ons op via telefoonnummer.';        
   }
   else
   {
      //Wat hij moet doen als alles in orde is
   }


De error die je geeft is overigens ook een beetje raar, er gaat niets fout hij is gewoon iets vergeten.
Alleen vergeet je nu de if toe te voegen :o.

Daarnaast zou je ook een variabele $error kunnen toewijzen, waarin je de foutmelding stopt, zodat je deze in de template kunt behandelen en kunt laten zien :).

  • koendenb
  • Registratie: Januari 2011
  • Laatst online: 19:15
alex3305 schreef op dinsdag 15 november 2011 @ 16:24:
[...]

Alleen vergeet je nu de if toe te voegen :o.

Daarnaast zou je ook een variabele $error kunnen toewijzen, waarin je de foutmelding stopt, zodat je deze in de template kunt behandelen en kunt laten zien :).
Lijkt me een beetje overbodig.. Ok het is wat lastig lezen maar anders krijg je overbodige if statements als het allemaal in 1 past.

Van die $error is handig, je kan er zelfs een array van maken zodat je al je errors van de website of form kan inzetten:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
$error = array(
   0 => "U bent vergeten om uw e-mailadres in te vullen.",
   1 => "U bent vergeten om uw telefoonnummer in te vullen.");
);

if(!isset($_POST['email']))
{
   echo $error[0];
}
elseif(!isset($_POST['telefoonnummer']))
{
   echo $error[1];
}


Tuurlijk zou je dit kunnen versimpelen, maar het gaat om het idee ;)

Succes er mee trouwens :)

[ Voor 0% gewijzigd door koendenb op 15-11-2011 16:36 . Reden: Typo :) ]


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:08
koendenbraven schreef op dinsdag 15 november 2011 @ 16:32:
[...]

Lijkt me een beetje overbodig.. Ok het is wat lastig lezen maar anders krijg je overbodige if statements als het allemaal in 1 past.

[...]
Nee, wat ik bedoelde is dat jouw syntax incorrect is. Dit had ik gefixed in de quote in mijn voorlaatste post :). Probeer het maar eens.

  • OkkE
  • Registratie: Oktober 2000
  • Laatst online: 10-11 15:46

OkkE

CSS influencer :+

koendenbraven schreef op dinsdag 15 november 2011 @ 16:32:
Tuurlijk zou je dit kunnen versimpelen, maar het gaat om het idee ;)

Succes er mee trouwens :)
Als we dan toch bezig zijn, vind ik jouw voorbeeld ook niet zo geweldig; een if-else is hier in mijn ogen niet zo slim. Wat nu als beide velden fout zijn?

Waarschijnlijk zou ik alle velden met hun labels, validatie-regels en error-teksten in een Array zetten. Zodat je de error's ook gelijk duidelijk gekoppeld hebt. Maar de errror tekst opbouwen zou ik sowieso altijd op zo'n manier doen:
.
PHP:
1
2
3
$error_msg = '';
if(!isset($_POST['email'])){ $error_msg .= 'E-mail ...'; }
if(!isset($_POST['telefoonnummer'])){ $error_msg .= 'Telefoon ...'; }

“The best way to get the right answer on the Internet is not to ask a question, it's to post the wrong answer.”
QA Engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 999999999 beers. Orders a lizard. Orders -1 beers.


  • MueR
  • Registratie: Januari 2004
  • Laatst online: 19:50

MueR

Admin Devschuur® & Discord

is niet lief

Schopje naar Programming

Anyone who gets in between me and my morning coffee should be insecure.


  • mr_fragle
  • Registratie: Oktober 2000
  • Laatst online: 12:46

mr_fragle

Don't forget the guide

Topicstarter
Bedankt allemaal voor de reactie. Ik ga er mee aan de slag. Een ding begrijp ik echter niet helemaal.

PHP:
1
2
3
4
5
6
7
8
9
10
    // Controle of waardes doorgegeven worden
    if(
        !isset($_POST['bedrijfsnaam']) ||                               
        !isset($_POST['contactpersoon']) ||                             
        !isset($_POST['email']) ||
        !isset($_POST['telefoonnummer']) ||                                 
        !isset($_POST['opmerking']))                                        
            {
            died('Het spijt ons, maar het lijkt erop dat er iets fout gaat. <br /> Neem contact met ons op via telefoonnummer.');       
            }


Wat checked bovenstaande code nou exact? Checked het of het uberhaubt een waarde 'bedrijfsnaam', of etc,etct ontvangt uit mijn html-form? Of checked het of de doorgegeven waarde 'bedrijfsnaam' is ingevuld? Als dat tweede het geval is, wat is dan het verschil met onderstaand stuk code (neem als voorbeeld even het veld bedrijfsnaam):

PHP:
1
2
3
4
    $string_exp = "/^[A-Za-z .'-]+$/";
  if(!preg_match($string_exp,$bedrijfsnaam)) {
    $error_message .= 'De ingevoerde bedrijfsnaam is ongeldig.<br />';
  }


Want als ik dit tweede deel code gebruik en ik vul in het html-form niks in bij bedrijsnaam, dan krijg ik de melding "De ingevoerde bedrijfsnaam is ongeldig". Ik krijg met mijn code nooit de foutmelding uit mijn eerste stuk code " Het spijt ons, maar het lijkt erop dat er iets fout gaat. <br /> Neem contact met ons op via telefoonnummer.".

And now the most interresting part of deze grot


  • alex3305
  • Registratie: Januari 2004
  • Laatst online: 22:08
In de eerste code check je of er überhaupt iets in een veld staat (bijv. bedrijfsnaam of telefoonnummer). Waarbij het niet uitmaakt wat erin staat of in welk veld het staat. Een OF conditie dus.

In de tweede code snippet check je met een reguliere expressie of er één van de volgende tekens in voortkomt. Reguliere expressies zijn erg prettig, maar niet altijd wenselijk. Wat nu als je een Arabisch bedrijf hebt, om maar iets geks te noemen?

Wel zou je trim kunnen gebruiken om in ieder geval whitespace voor en achter de tekst eruit te filteren.

  • mr_fragle
  • Registratie: Oktober 2000
  • Laatst online: 12:46

mr_fragle

Don't forget the guide

Topicstarter
Ok, dat snap ik. Dat is ook wat ik dacht. Maar hoe kan het dan zijn dat als ik niks invul in mijn formulier, en vervolgens op verzenden druk, ik de mededeling van de onderste code krijg? Ik krijg nooit de melding uit de bovenste code :?

And now the most interresting part of deze grot


  • Spinal
  • Registratie: Februari 2001
  • Laatst online: 18-11 15:23
Omdat je formulier lege velden ook gewoon verstuurd :) isset($_POST['bedrijfsnaam']) geeft TRUE terug, maar de waarde is leeg.

Full-stack webdeveloper in Groningen


  • DataGhost
  • Registratie: Augustus 2003
  • Laatst online: 10:26

DataGhost

iPL dev

Daarnaast een klein wtfje betreffende de logica:
Het enige dat ik nog zou willen is dat de bedrijfsnaam niet vereist is, maar dat als de bedrijfsnaam is ingevuld, dat dan ook alleen de door mij gespecificeerde tekens daarin mogen voorkomen.
Ik denk dan aan
code:
1
2
3
4
5
6
7
als b niet is ingevuld 
    of c niet is ingevuld 
    of d niet is ingevuld 
    of (a is ingevuld en niet voldoet aan mijn regels)
{
  geef een foutmelding
}

versus de en-logica die ik hierboven heb gezien. (!a || !b) == !(a && b) != (!a && !b). Met de code van alex en koen krijg je dus ook alleen de foutmelding als (bijna) alle velden niet zijn ingevuld, als slechts een van de velden niet is ingevuld zal je geen fout zien. Dit alles inderdaad nog afgezien van het op de verkeerde manier gebruiken van isset().

[ Voor 8% gewijzigd door DataGhost op 17-11-2011 10:08 . Reden: quote uitgebreid ]


Verwijderd

Volgens mij wil je controleren of de velden zijn ingevuld of niet. Dit kan je beter met de Empty functie van php doen.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
<?php 
    // Controle of waardes doorgegeven worden 
    if( 
        empty($_POST['bedrijfsnaam']) ||                                   
        empty($_POST['contactpersoon']) ||                               
        empty($_POST['email']) || 
        empty($_POST['telefoonnummer']) ||                                   
        empty($_POST['opmerking']))                                           
            { 
            died('Het spijt ons, maar het lijkt erop dat er iets fout gaat. <br /> Neem contact met ons op via telefoonnummer.');        
            } 
?> 

  • Keiichi
  • Registratie: Juni 2005
  • Laatst online: 12:19
waarom een function statement IN een if statement plaatsen?

Solar @ Dongen: http://solar.searchy.net/ - Penpal International: http://ppi.searchy.net/


  • Keeper
  • Registratie: Juni 2001
  • Niet online

Keeper

<3 Ruby

Keiichi schreef op donderdag 17 november 2011 @ 10:46:
waarom een function statement IN een if statement plaatsen?
Waarom niet? Wat is er mis met:

PHP:
1
2
3
if(empty($foo)) {
    // do stuff
}


@TS, met isset() check je of ten variabele bestaat (en de waarde niet null is). In een array test je dus met isset() of die key wel bestaat (en in dit geval of dat veld wel gePOST is). Dat is vrij zinloos, want bij een standaard POST van een HTML form worden al je velden meegestuurd. Je kan beter checken op empty(), dit kijkt of de waarde die wordt gePOST leeg is (lege string, null, false, whatever).

PHP:
1
2
3
4
5
6
7
8
9
$test = array('foo' => 'bar', 'baz' => null);

var_dump(isset($test['foo'])); // true
var_dump(isset($test['baz'])); // false
var_dump(isset($test['bat'])); // false

var_dump(empty($test['foo'])); // false
var_dump(empty($test['baz'])); // true
var_dump(empty($test['bat'])); // true


Specifiek voor je check op de bedrijfsnaam zou je dus willen controleren of de bedrijfsnaam leeg is OF dat hij voldoet aan je regex. Dus in pseudo php:

PHP:
1
2
3
4
5
if(empty($bedrijfsnaam) || preg_match($pattern, $bedrijfsnaam)) {
    // input is goed
} else {
    // input is niet goed
}

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 19:50

MueR

Admin Devschuur® & Discord

is niet lief

Het lijkt me een heel tof idee als de TS iets meer moeite gaat steken in het opzoeken van functies en dergelijke in de manual. Het begint langzaam richting het handje-vasthouden niveau te zakken.

Anyone who gets in between me and my morning coffee should be insecure.

Pagina: 1