0

My form has worked fine, but now I have a problem with my form: no mail is sent even if the form is correct and complete, no error message if the input is not correct (e.g address mail or phone number or min. lenght of input name).

The (last) PHP version of host is 5.6.10.

Please, can somebody help me? Thx.

The form code:

<?php session_start(); ?>
<!DOCTYPE....>

<head>
...
</head>

<body>
    ...
    ...

    <?php include 'scripts/contact.php'; ?>

     <form action="Contact.php" method="post" accept-charset="UTF-8">
      <table id="formular">
       <tr>
        <td><label for="nume">Nume:&nbsp;<span style="color: red"><sup>*</sup></span>&nbsp;</label></td>
        <td><input type="text" name="nume" id="nume" maxlenght="20" value="<?php echo $_POST['nume']; ?>" /></td>
        <td><span class="err"><?php if(isset($errors['nume'])&&$error) { print $errors['nume']; } ?></span></td>
       </tr>

       <tr>
        <td><label for="prenume">Prenume:&nbsp;<span style="color: red"><sup>*</sup></span>&nbsp;</label></td>
        <td><input type="text" name="prenume" id="prenume" maxlenght="20" value="<?php echo $_POST['prenume']; ?>" /></td>
        <td><span class="err"><?php if(isset($errors['prenume'])&&$error) { print $errors['prenume']; } ?></span></td>
       </tr>

       <tr>
        <td><label for="telefon">Telefon:&nbsp;<span style="color: red"><sup>*</sup></span>&nbsp;</label></td>
        <td><input type="text" name="tel" id="tel" maxlenght="20" value="<?php echo $_POST['tel']; ?>" /></td>
        <td><span class="err"><?php if(isset($errors['tel'])&&$error) { print $errors['tel']; } ?></span></td>
       </tr>

       <tr>
        <td><label for="email">Email:&nbsp;<span style="color: red"><sup>*</sup></span>&nbsp;</td>
        <td><input type="text" name="email" id="email" maxlength="50" value="<?php echo $_POST['email']; ?>" /></label></td>
        <td><span class="err"><?php if(isset($errors['email'])&&$error) { print $errors['email']; } ?></span></td>
       </tr>

 <tr>
        <td><label for="mesaj">Mesaj:&nbsp;<span style="color: red"><sup>*</sup></span>&nbsp;</label></td>
        <td><textarea cols="20" rows="5" wrap="virtual" id="mesaj" name="mesaj" maxlength="150" onkeyup="nrcaractere()"><?php echo $_POST['mesaj']; ?></textarea><br>
        <div id="ramase">150 chars remaining</div>
        <script type="text/javascript">window.ready = nrcaractere();</script></td>
        <td><span class="err"><?php if(isset($errors['mesaj'])&&$error) { print $errors['mesaj']; } ?></span></td>
       </tr>

  <tr>
        <td></td> 
        <td align="center">
         <button type="submit" name="trimite" />Trimite</button>
         <button type="button" name="reset" onClick="sterge()" />Reset</button></td>
        <td></td>
       </tr>
      </table>
     </form>
...
...

and the validation script:

<?php
 if (isset($_POST['trimite']))
 { $error = FALSE;

 if (empty($_POST['nume'])) {
   $errors['nume']='&nbsp;Mandatory';
   $error = TRUE;
 }
 else {       
   if (!preg_match('/^[a-zA-Z]{1,}$/',$_POST['nume'])) {
      $errors['nume']='&nbsp;Only letters';
      $error = TRUE;
   } 
   else {           
      if (strlen($_POST['nume'])<3) {
         $errors['nume']='&nbsp;Too short. Min. 3 chars';
         $error = TRUE;
      }
      else {
         $errors['nume']='<img src=/images/ok.jpg>';
      }
    }
  }

 if (empty($_POST['prenume'])) {
   $errors['prenume']='&nbsp;Mandatory';
   $error = TRUE;
 }
 else {       
   if (!preg_match('/^[a-zA-Z]{1,}$/',$_POST['prenume'])) {
      $errors['prenume']='&nbsp;Only letters';
      $error = TRUE;
   } 
   else {           
      if (strlen($_POST['prenume'])<3) {
         $errors['prenume']='&nbsp;Too short. Min. 3 chars';
         $error = TRUE;
       }
       else {
           $errors['prenume']='<img src=/images/ok.jpg>';
       }
   }
 }

 if (empty($_POST['tel'])) {
   $errors['tel']='&nbsp;Mandatory';
   $error = TRUE;
 }
 else {       
   if ( !preg_match('/^[0-9]{4}[\s.]{0,1}[0-9]{3}[\s.]{0,1}[0-9]{3}$/', $_POST['tel']) && !preg_match('/^[0-9]{3}[\s.]{0,1}[0-9]{3}[\s.]{0,1}[0-9]{2}[\s.]{0,1}[0-9]{2}$/', $_POST['tel']) && ($_POST['tel'] != '-')) {
     $errors['tel']='&nbsp;Mask: 021.021.02.01 or 0740.123.456 or -';
     $error = TRUE;
   }
   else {
     $errors['tel']='<img src=/images/ok.jpg>';
   }
 }

 if (empty($_POST['email'])) {
   $errors['email']='&nbsp;Mandatory';
   $error = TRUE;
 }
 else {       
   if (!preg_match('/^[a-z0-9&\'\.\-_\+]+@[a-z0-9\-]+\.([a-z0-9\-]+\.)*+[a-z]{2}/is', $_POST['email'])) {
     $errors['email']='&nbsp;Invalid address';
     $error = TRUE;
   }
   else {
       $errors['email']='<img src=/images/ok.jpg>';
   }
 }

 if (empty($_POST['mesaj'])) {
   $errors['mesaj']='&nbsp;Mandatory';
   $error = TRUE;
 }
 else {       
   if (strlen($_POST['mesaj'])<15) {
      $errors['mesaj']='&nbsp;Too short. Min. 15 chars';
      $error = TRUE;
   }
   else {
      if (strlen($_POST['mesaj'])>150) {
        $errors['mesaj']='&nbsp;Too long. Max. 150 chars';
        $error = TRUE;
      }
      else {
         $errors['mesaj']='<img src=/images/ok.jpg>';
      }
    }
 }

 if (!$error) {
  $destinatar = "my_address@yahoo.com";
  $subject = "Site message";
  $body = 'Nume: '.$_POST['nume'].'
  <br>
  Prenume: '.$_POST['prenume'].'
  <br>
  Telefon: '.$_POST['tel'].'
  <br>
  Email: '.$_POST['email'].'
  <br><br>
  Mesaj: '.$_POST['mesaj'];
  $headers .= 'MIME-Version: 1.0' . "\r\n";
  $headers .= 'Content-type: text/html; charset=UTF-8' . "\r\n";

  if (mail($destinatar,$subject,$body,$headers)) {
     echo '<script type="text/javascript">alert("Message sent!")</script>';
     unset($_POST);
  }
  else {
     echo '<script type="text/javascript">alert("Not sent. Try again!")</script>';
  }
 }
}

 $_SESSION['s']=$s;
 ?>

PS. Excuse my bad English.

colombo2003
  • 121
  • 9

2 Answers2

1

It sounds like you have two problems, one with validation, and one with sending email. Tackle the easiest first: start off by finding out if your mail set up is correct -- can php normally send email, or it a problem with your code? I use the following php script to tell me if the server is set up correctly for out-going emails:

<?php 
    ini_set( 'display_errors', 1 );
    error_reporting( E_ALL );
    $from = "<YOUR EMAIL>";
    $to = "<YOUR EMAIL>";
    $subject = "PHP Mail Test script";
    $message = "This is a test to check the PHP Mail functionality";
    $headers = "From:" . $from;
    mail($to,$subject,$message, $headers);
    echo "Test email sent";
?>

It doesn't work, you need to configure the server to let php send email. I like to use the ssmtp daemon to simplify sending email to an SMTP server.

As for your validation code, it's quite hard to follow. Have you considered using a validation library instead? You could even use raw HTML5 -- see here: http://www.the-art-of-web.com/html/html5-form-validation/.

But if you really want to use your own php validator, personally I would write something like the following:

<?php 
$validation_elements = array(
    'nume' => function() {
        if (!isset($_POST['nume'])) return 'You must enter your nume';
        if (!preg_match('/^[a-zA-Z]{1,}$/',$_POST['nume']) return 'Your nume can only be letters.;'
        return false;
    },
    'prenume' => function() {
        if (!isset($_POST['Mandatory'])) return 'Your prenume is mandatory';
        if (!preg_match('/^[a-zA-Z]{1,}$/',$_POST['prenume'])) return "Your presume can only consist of letters";
        if (strlen($_POST['prenume'])<3) return "Your presume is too short.";   
        return false;
    }, 
    'tel' => function() {
        if (!isset($_POST['tel']) return false; // in this example tel is not mandatory but must match the following rule if it is present:
        if ( !preg_match('/^[0-9]{4}[\s.]{0,1}[0-9]{3}[\s.]{0,1}[0-9]{3}$/', $_POST['tel']) && !preg_match('/^[0-9]{3}[\s.]{0,1}[0-9]{3}[\s.]{0,1}[0-9]{2}[\s.]{0,1}[0-9]{2}$/', $_POST['tel']) && ($_POST['tel'] != '-')) return '&nbsp;Mask: 021.021.02.01 or 0740.123.456 or -';     
        return false;  
    },
    'email' => function() {
        if (!isset($_POST['email'])) return 'Your email is mandatory';
        if (!preg_match('/^[a-z0-9&\'\.\-_\+]+@[a-z0-9\-]+\.([a-z0-9\-]+\.)*+[a-z]{2}/is', $_POST['email'])) return "Your email address must be like something@something.something";
        return false;
    },
    'mesaj' => function() {
        if (!isset($_POST['mesaj'])) return 'Your mesaj is mandatory';  
        if (strlen($_POST['mesaj'])<15) return 'Mesaj too short. Min. 15 chars';
        if (strlen($_POST['mesaj'])>150) return 'Mesaj too long. Max 150 chars.';
        return false;
    }
}

foreach ($validation_elements as $validation_element => $validation_rule) {
    $errors = array();
    if ($validation_rule()) {
        $errors[] = $validation_rule($validation_element);
    }
}
if (!empty($errors)) {
    echo "The form was not completed because: <ul>";
    foreach ($errors as $error) {
        echo "<li>$error</li>";
    }
    echo "</ul>";
} else {
    send_email();
}

The rationale is that validation is a repetitive task -- we take an input and apply rules to it to see if it passes or fails -- so we should wrap it in a loop instead of doing it procedurally, as in your example. The best input for that kind of data is an associative array where the value is the function to be performed on the data. Most good validation libraries will ask you to make your rules something like this:

<?php
 $validation = array(
    'tel' => array(
        'required' => true
     ),
     'mesaj' => array(
         'lessThan' => 150,
         'moreThan' => 15,
         'alphanumeric' => true
      ),
     <etc.>

... but if you want to write something as fully-featured as that, I'll leave it up to you to figure out how.

Finally, a word about validation -- it's hard, and most programmers get it wrong. You must very carefully evaluate even the most unexpected possibilities for valid data.

For example: if I try to write you a message, will my phone be considered valid? I have a UK phone number which can take the form +44 xxxxx xxxxx, 0xxxxxxxxxx, or even (+44) xxxxx xxxxx.

Your current validation rules may look good to you, but will Mrs. O'Shea or Ms. O'connor be able to send you a message? What about Mr. Mac Duff? How about Dr. Ng from Singapore or even Prof. Nil from the US? Or for first names, what about Ms. An Wilde? All of these are perfectly valid names, even if they are not typical among your expected users. I even know a man named Ben X, though it isn't his registered name.

Good luck!

DMCoding
  • 1,167
  • 2
  • 15
  • 30
1

The problem with my previous answer is it is not portable -- you can't take that code and use it elsewhere. In my previous answer, I hinted that there was another, better way of writing a validation routine. Here it is. It's more complex, but only slightly so.

<?php
$validation_rules = array(
    'tel' => array(
        'required' => true
    ),
    'mesaj' => array(
        'lessThan' => 150,
        'moreThan' => 15,
        'alphanumeric' => true
    ), <etc>
);

$errors = array();

/* Note: you could also write each validation rule like this:
function required($input, $is_required) {
    ... <etc>
} 
The function name is the name of the validation rule in the above array.*/

$validation_types = array() {
    'required' => function($input, $is_required) {
        $isset = isset($_POST[$input]));
        return ($is_required && !$isset) ? "$input is required" : false;
    },
    'alphanumeric' => function($input, $is_required) {
        return preg_match('/^[a-zA-Z]{1,}$/',$_POST[$input] ? "$input must be alphanumeric" : false;
    },
    'likeEmail' => function($input, $is_required) {
        return !preg_match('/^[a-z0-9&\'\.\-_\+]+@[a-z0-9\-]+\.([a-z0-9\-]+\.)*+[a-z]{2}/is', $_POST[$input]) ? "$input must be like an email address" : false;
    },
    'lessThan' => function($input, $value) {
        return (!strlen($input) < $value) ? "$input must be less than $value" : false;
    }, <etc>
}
foreach ($validation_rules as $input=>$rules) {
    foreach($rules as $rule=>$params) {
        $validation_failed = $validation_types[$rule]($input, $params);
        // if you used the simpler way of declaring validation rules,use this instead:
        // $validation_failed = $rule($input, $params);
        if ($validation_failed) {
            $errors[] = $validation_failed;
        }
    }
}

The reason this code is better is because it can be used in other forms as well, but its not much more complicated to read.

DMCoding
  • 1,167
  • 2
  • 15
  • 30