title: Special characters (utf-8) in PHP contact message
body: <p>I have a contact form. When i receive a message, i can not read it normally because the special characters are shown bizarrly. </p>
  
  <p>I saved my file in utf-8 without BOM, I red and tried a lot of variations about this subject but I could not find the right answer for myself.</p>
  
  <p>The contact form in my html :</p>
  
  <pre><code>&lt;meta charset="utf-8" /&gt;
  &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt; 
  
  
  &lt;form id="contactform" action="processform.php" method="post" accept-charset='UTF-8'&gt;
      &lt;div class="form-label label-name"&gt;Nom&lt;/div&gt;
      &lt;input type="text" name="name" id="name" /&gt;
      &lt;div class="form-label label-postcode"&gt;Code Postal&lt;/div&gt;
      &lt;input type="text" name="postcode" id="postcode" /&gt;
      &lt;div class="form-label label-email"&gt;E-mail&lt;/div&gt;
      &lt;input type="text" name="email" id="email" /&gt;
      &lt;div class="form-label label-subject"&gt;Sujet&lt;/div&gt;
      &lt;input type="text" name="subject" id="subject" /&gt;
      &lt;div class="form-label label-message"&gt;Message&lt;/div&gt;
      &lt;textarea rows="4" name="message" id="message"&gt;&lt;/textarea&gt;
      &lt;input type="submit" id="send" name="button" value="Envoyer" /&gt;           
  &lt;/form&gt;
  </code></pre>
  
  <p>My processform.php file (saved in UTF-8 without BOM) has the following codes :</p>
  
  <pre><code>&lt;?php
  
  include_once $_SERVER['DOCUMENT_ROOT'] . '/securimage/securimage.php';
  
  $securimage = new Securimage();
  
  if ($securimage-&gt;check($_POST['verif']) == false) {
    // the code was incorrect
    // you should handle the error so that the form processor doesn't continue
  
    // or you can use the following code if there is no validation or you do not know how
    echo "Le code de s&amp;eacute;curit&amp;eacute; indiqu&amp;eacute; est incorrect.&lt;br /&gt;";
    echo "Rafra&amp;icirc;chissez la page et essayez &amp;agrave; nouveau svp.";
    exit;
  }
  
  // Clean up the input values
  foreach($_POST as $key =&gt; $value) {
    if(ini_get('magic_quotes_gpc'))
      $_POST[$key] = stripslashes($_POST[$key]);
  
    $_POST[$key] = htmlspecialchars(strip_tags($_POST[$key]));
  }
  
  // Assign the input values to variables for easy reference
  $name = $_POST["name"];
  $email = $_POST["email"];
  $subject = $_POST["subject"];
  $message = $_POST["message"];
  
  // Test input values for errors
  $errors = array();
  if(strlen($name) &lt; 3) {
    if(!$name) {
      $errors[] = "Entrez votre nom svp.";
    } else {
      $errors[] = "Au moins 3 caractères sont requis pour un nom.";
    }
  }
  if(!$email) {
    $errors[] = "Entrez votre email svp.";
  } else if(!validEmail($email)) {
    $errors[] = "Veuillez fournir une adresse valide svp.";
  }
  if(strlen($message) &lt; 20) {
    if(!$message) {
      $errors[] = "Entrez un message svp.";
    } else {
      $errors[] = "Au moins 20 caractères sont requis pour un message.";
    }
  }
  
  if($errors) {
    // Output errors and die with a failure message
    $errortext = "";
    foreach($errors as $error) {
      $errortext .= "&lt;li&gt;".$error."&lt;/li&gt;";
    }
    die("&lt;span class='failure'&gt;Les erreurs suivantes sont survenues :&lt;ul&gt;". $errortext ."&lt;/ul&gt;&lt;/span&gt;");
  }
  
  // Remplacement de certains caractères spéciaux
  header('Content-Type: text/html; charset=utf-8');
  
  // Send the email
  $to = "myemail@gmail.com";
  $message = "
  From: $name 
  Email: $email 
  Subject: $subject
  Message: $message";
  $headers = "Message from West Hungary website";
  
  mail($to, $subject, $message, $headers);
  
  // Die with a success message
  die("&lt;span class='success'&gt;Votre message a &amp;eacute;t&amp;eacute; envoy&amp;eacute; avec succ&amp;egrave;s !&lt;/span&gt;");
  
  // A function that checks to see if
  // an email is valid
  function validEmail($email)
  {
     $isValid = true;
     $atIndex = strrpos($email, "@");
     if (is_bool($atIndex) &amp;&amp; !$atIndex)
     {
        $isValid = false;
     }
     else
     {
        $domain = substr($email, $atIndex+1);
        $local = substr($email, 0, $atIndex);
        $localLen = strlen($local);
        $domainLen = strlen($domain);
        if ($localLen &lt; 1 || $localLen &gt; 64)
        {
           // local part length exceeded
           $isValid = false;
        }
        else if ($domainLen &lt; 1 || $domainLen &gt; 255)
        {
           // domain part length exceeded
           $isValid = false;
        }
        else if ($local[0] == '.' || $local[$localLen-1] == '.')
        {
           // local part starts or ends with '.'
           $isValid = false;
        }
        else if (preg_match('/\\.\\./', $local))
        {
           // local part has two consecutive dots
           $isValid = false;
        }
        else if (!preg_match('/^[A-Za-z0-9\\-\\.]+$/', $domain))
        {
           // character not valid in domain part
           $isValid = false;
        }
        else if (preg_match('/\\.\\./', $domain))
        {
           // domain part has two consecutive dots
           $isValid = false;
        }
        else if(!preg_match('/^(\\\\.|[A-Za-z0-9!#%&amp;`_=\\/$\'*+?^{}|~.-])+$/',
                   str_replace("\\\\","",$local)))
        {
           // character not valid in local part unless
           // local part is quoted
           if (!preg_match('/^"(\\\\"|[^"])+"$/',
               str_replace("\\\\","",$local)))
           {
              $isValid = false;
           }
        }
        if ($isValid &amp;&amp; !(checkdnsrr($domain,"MX") || checkdnsrr($domain,"A")))
        {
           // domain not found in DNS
           $isValid = false;
        }
     }
     return $isValid;
  }
  
  ?&gt;
  </code></pre>