Avatar billede visto Professor
05. april 2012 - 11:05 Der er 13 kommentarer og
1 løsning

Formmail, problem med æ ø å, charset=UTF-8

Jeg har læst en masse indlæg om samme type problem uden dog at kunne finde løsningen, så her kommer endnu et spørgsmål i genren.

Jeg skal bruge en formail på en php-side, som er gemt i formatet UTF-8 uden BOM, og i head har jeg:
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
Problemet er at æ ø og å vises forkert i de genererede mails, både når bogstaverne indgår i afsendes navn, emne og selve teksten.

Hvad mangler jeg for at få vist bogstaverne korrekt?

Formen ser sådan ud:

<form method="post" action="sender.php">

<label for="t1">Dit navn:</label><br />
<input class="form-input" id="t1" type="text" size="20" name="name"/><br /><br />

<label for="t2">Din e-mail-adresse:</label><br />
<input class="form-input" id="t2" type="text" size="20" name="email" /><br /><br />

<label for="t3">Emne:</label><br />
<input class="form-input" id="t3" type="text" size="20" name="emne" /><br /><br />

<!-- næste input skjules med css for almindelige brugere, kun spambotter ser (og udfylder sandsynligvis) feltet -->

<span id="ikkese"><label for="t7">Subject:</label>
<input id="t7" type="text" name="subject" /></span>

<label for="t4">Besked:</label><br />
<textarea class="besked-input" id="t4" name="besked" rows="10" cols="49"></textarea><br />

<label for="t5">Ønsker du kopi af mailen?</label>
<input id="t5" type="checkbox" name="customer_copy" value="ON" />

<label for="t6">&nbsp;</label><input id="t6" type="submit" name="submit" value=" Send " />

</form>

Den tilhørende sender.php ser sådan ud:

<?php
if (isset($_POST['submit']))
{
if (!empty($_POST['name']) && // tjek, at der er skrevet et navn
!empty($_POST['email']) &&    // tjek, at der er skrevet en e-mail-adresse
!empty($_POST['emne']) &&  // tjek, at der er skrevet et emne
!empty($_POST['besked']) &&  // tjek, at der er skrevet en besked

// her følger sikringen mod spambotter
!strpos($_POST['name'], "mit_domaene.dk") &&  // tjek, at dit domæne ikke er skrevet i feltet "navn"
!strpos($_POST['email'], "mit_domaene.dk") && // tjek, at dit domæne ikke er skrevet i feltet "email"
!strpos($_POST['name'], "@") && // tjek, at der ikke er et @ i "navn"
!eregi("\r",$_POST['name']) &&  // tjek, at der ikke er "vogn-retur" i "navn"
!eregi("\n",$_POST['name']) &&  // tjek, at der ikke er "linjeskift" i "navn"
!eregi("\r",$_POST['email']) && // tjek, at der ikke er "vogn-retur" i "email"
!eregi("\n",$_POST['email']))  // tjek, at der ikke er "linjeskift" i "email"

// er alt ok, fortsættes med afsendelse af mailen
{
  $headers="From: ".$_POST['name']."<".$_POST['email'].">";
  if (@$_POST['customer_copy'])
  {
  $headers .= "\r\nBcc: ".$_POST['email'];
  }
  $body .= "Den " . date("d/m y") . " kl. " . date("G:i") . " skrev " . $_POST['name'] . ":\r\n\r\n" . $_POST['besked'];
  if (@mail("info@mit_domaene.dk", strip_tags($_POST['emne']),
  stripslashes(strip_tags($body)), $headers))
  {
  echo "<p class=\"besked\">Beskeden er sendt.</p>";
  }
  else
  {
  echo "<p class=\"besked\">E-mailen kunne ikke sendes. Mail-adressen er forkert udfyldt. Du mangler sandsynligvis @.</p>";
  }
}
else
{
  echo "<p class=\"besked\">Mailen kunne ikke sendes. Alle felter skal udfyldes.</p>";
}
}
?>
Avatar billede olsensweb.dk Ekspert
05. april 2012 - 11:26 #1
prøv at læse denne tråd http://www.eksperten.dk/spm/956890
fra #1
umildbart mangler du nogle headers
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/plain; charset=utf-8\r\n";
$headers .="Content-Transfer-Encoding: 8bit";

en nemmere løsning er at bruge den function olebole har vist i #3
Avatar billede visto Professor
05. april 2012 - 11:49 #2
Den tråd havde jeg læst. Det er umuligt for mig at forstå. Jeg er så afgjort ikke programmeringskyndig og har brug for ret præcise anvisninger om hvad der skal indsættes hvor i min kode.
Avatar billede olsensweb.dk Ekspert
05. april 2012 - 12:23 #3
utested
<?php
if (isset($_POST['submit']))
{
if (!empty($_POST['name']) && // tjek, at der er skrevet et navn
!empty($_POST['email']) &&    // tjek, at der er skrevet en e-mail-adresse
!empty($_POST['emne']) &&  // tjek, at der er skrevet et emne
!empty($_POST['besked']) &&  // tjek, at der er skrevet en besked

// her følger sikringen mod spambotter
!strpos($_POST['name'], "mit_domaene.dk") &&  // tjek, at dit domæne ikke er skrevet i feltet "navn"
!strpos($_POST['email'], "mit_domaene.dk") && // tjek, at dit domæne ikke er skrevet i feltet "email"
!strpos($_POST['name'], "@") && // tjek, at der ikke er et @ i "navn"
!eregi("\r",$_POST['name']) &&  // tjek, at der ikke er "vogn-retur" i "navn"
!eregi("\n",$_POST['name']) &&  // tjek, at der ikke er "linjeskift" i "navn"
!eregi("\r",$_POST['email']) && // tjek, at der ikke er "vogn-retur" i "email"
!eregi("\n",$_POST['email']))  // tjek, at der ikke er "linjeskift" i "email"

// er alt ok, fortsættes med afsendelse af mailen
{
  $headers="From: ".$_POST['name']."<".$_POST['email'].">\r\n";
  $headers .= "MIME-Version: 1.0\r\n";
  $headers .= "Content-type: text/plain; charset=utf-8\r\n";
  $headers .="Content-Transfer-Encoding: 8bit";

  if (@$_POST['customer_copy'])
  {
  $headers .= "\r\nBcc: ".$_POST['email'];
  }
  $body .= "Den " . date("d/m y") . " kl. " . date("G:i") . " skrev " . $_POST['name'] . ":\r\n\r\n" . $_POST['besked'];
  if (@mail("info@mit_domaene.dk", strip_tags($_POST['emne']),
  stripslashes(strip_tags($body)), $headers))
  {
  echo "<p>Tak for din kommentar.</p>";
  }
  else
  {
  echo "<p>Der opstod en teknisk fejl. Prøv venligst igen!</p>";
  }
}
else
{
  echo "<p>Et eller flere felter mangler at blive udfyldt!</p>";
}
}
?>

husk at rette mit_domaene.dk til det rigtige

men prøv at kigge på http://www.eksperten.dk/spm/956890 #7 og #9, der bruger olebole's function
Avatar billede visto Professor
05. april 2012 - 14:20 #4
Mange tak! De vigtige ting virker nu, dvs. indholdet i mailen er korrekt.
Der resterer, at afsenders navn stadig står med krusseduller på æ, ø og å's pladser i - ja hvad kalder man den - den linje i mailprogrammet (Outlook Express), der viser "Fra", "Emne", "Modtaget", "Konto", "Størrelse" osv.

Hvad skal der til for at afhjælpe det?
Avatar billede olsensweb.dk Ekspert
05. april 2012 - 15:02 #5
prøv at incode subject

if (@mail("info@mit_domaene.dk", strip_tags($_POST['emne']),  stripslashes(strip_tags($body)), $headers))


rettest til

if (@mail("info@mit_domaene.dk","=?utf-8?B?".base64_encode(strip_tags($_POST['emne']))."?=",  stripslashes(strip_tags($body)), $headers))


jeg kan se du har coden herfra http://www.hjemmesideskolen.dk/scripts/phpmail.php
Avatar billede visto Professor
05. april 2012 - 15:27 #6
Det gør ingen forskel.
Avatar billede olsensweb.dk Ekspert
05. april 2012 - 17:59 #7
hvis vi kigger på olebole's 2 funtioner i http://www.eksperten.dk/spm/956890 #3, kan man se han også base64_encode name så prøv dette:

$headers="From: ".$_POST['name']."<".$_POST['email'].">\r\n";


laves om til
function escapeAddr($addr) {
    $check = preg_match('/(.*)<(.*)>/', $addr, $a);
    if ($check) $addr = '=?UTF-8?B?'.base64_encode($a[1]).'?= <'.$a[2].'>';
    return $addr;
}

$from = $_POST['name']."<".$_POST['email'].">";
echo $from; // hvad skriver den her, test om æøå står rigtigt her, denne linje skal slettes senere
$from = escapeAddr($from);
$headers="From: ".$from."\r\n";


hvis det virker bør du selvføgelig også kigge på to, cc, bcc, da de vil have sammen problem

der er dog en ulempe ved http://dk.php.net/base64_encode , det fylder
Avatar billede visto Professor
05. april 2012 - 18:24 #8
Bingo! Så virker det hele.

Hvis du gider, vil jeg være glad for at du lige på jævnt dansk kort forklarer, hvad de koder, der er indsat gør.

Jeg forstår i øvrigt ikke rigtig hvad cc og bcc gør godt for i sender.php. Der er jo i selve mailformen kun mulighed for at sende en besked ét sted hen, nemlig til vedkommende, der har sitet, hvorpå formen ligger. Ingen bcc og cc-felter. Så jeg spørger mig selv om koder vedr. cc og bcc blot er med, fordi sender.php oprindelig har været brugt til en mere udvidet mail-funktionalitet?

Jeg kan i hvert fald konstatere, at både mailen sendt til site-indehaver og kopien til afsender står med korrekte æ ø og å alle steder. Så jeg har intet ændret for cc og bcc's vedkommende.

Jeg siger mange tak for rigtig god hjælp. Læg venligst svar til point. - Og god påske.
Avatar billede olsensweb.dk Ekspert
05. april 2012 - 20:24 #9
"Content-type: text/plain; charset=utf-8\r\n"; = definerer hvilke type indholdet af mailen er af, og dens tegnsæt
"Content-Transfer-Encoding: 8bit"; = i hvilke format er indholdet af vores mail kodet og overført i 7/8 bit
så er indholdet på plads, men vi mangler selve mail addresserne (to, from, cc, bcc), samt subject
disse skal encodes seperat, med base64_encode, for at mail serveren kan håndtere dem rigtigt


>Så jeg har intet ændret for cc og bcc's vedkommende.
du har da en checkbox til customer_copy
<input id="t5" type="checkbox" name="customer_copy" value="ON" />

du tester her
if (@$_POST['customer_copy'])
{
  $headers .= "\r\nBcc: ".$_POST['email'];
}

men der får du selvføgelig ikke navn med over, men ellers er løsningen jo escapeAddr

det kan godt betale sig at grave sig ned i disse link
mail
base64_encode

jeg ser ole havde brugt PHP_EOL istedet for \r\n da dette tager højde for platfors forskelligheder på linux skal det være \n, det er da værd at overveje
http://dk.php.net/manual/en/reserved.constants.php
Avatar billede visto Professor
06. april 2012 - 09:45 #10
Tak også for det.

Jeg har ikke rørt ved Bcc, kun foretaget de rettelser og tilføjelser, som er angivet ovenfor, men både mail til site-indehaver og kopi til afsender er korrekt mht. æ, ø, å både i indhold og i "linjen" med angivelse af afsender. Jeg kan ikke argumenter for hvorfor, men blot konstatere at det virker som det skal.

For at lette arbejdet for andre i samme situation, kan jeg sammenfatte til, at i sender.php rettes
$headers="From: ".$_POST['name']."<".$_POST['email'].">";
til:
  function escapeAddr($addr) {
    $check = preg_match('/(.*)<(.*)>/', $addr, $a);
    if ($check) $addr = '=?UTF-8?B?'.base64_encode($a[1]).'?= <'.$a[2].'>';
    return $addr;
}
$from = $_POST['name']."<".$_POST['email'].">";
$from = escapeAddr($from);
$headers="From: ".$from."\r\n";
  $headers .= "MIME-Version: 1.0\r\n";
  $headers .= "Content-type: text/plain; charset=utf-8\r\n";
  $headers .="Content-Transfer-Encoding: 8bit";
Avatar billede olsensweb.dk Ekspert
06. april 2012 - 12:02 #11
tfp
i din sammenfatning glemte du, at du også incoder subject (#5), da dette også vil give problemer med æøå
lige nu behøver du ikke gøre noget ved BCC, da du kun anvender mail addresssen, havde du derimod skulle have både navn og mail addresse så skulle du incode, da navn kan indeholde æøå
Avatar billede visto Professor
06. april 2012 - 13:01 #12
Da anvisningerne i #5 ikke gjorde nogen forskel, gik jeg tilbage og undlod altså de foreslåede rettelser.
Jeg kan jo ikke påstå at jeg forstår, hvad der sker. Jeg kan kun konstatere hvad der virker, hvad der ikke virker, og hvad der ikke gør nogen forskel.
Avatar billede olsensweb.dk Ekspert
06. april 2012 - 13:07 #13
har du prøvet at sende en mail med æøå i emne feltet :)
Avatar billede visto Professor
06. april 2012 - 13:43 #14
Yep.
æøå i både navn, emne og besked.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester