19 besökare, 1 medlem och 2 Studenter är online nu
Loopia

PHP och MySQL

Den här guiden visar hur du använder funktionen MAIL och skickar formulärdata till en e-postadress.

Dessutom visas hur du kontrollerar ditt formulär med enkel validering av att formulärfälten är ifyllda och validering av epostadresser med PREG_MATCH och REGEXP.

Med HTTP_REFERER och SESSIONS kontrollerar du att Formmail skickas från just ditt formulär för att undvika att formuläret spammas.

 

Prova funktionerna i ett Formmail-script

Klicka här för att prova exemplet nedan

OBS! Inga uppgifter sparas och formulärinnehållet skickas inte någonstans. Du kan prova att skicka meddelandet flera gånger och testa gärna att utelämna information i vissa fält.

Prova att ange en ogiltig epostadress för att testa om Formmail kontrollerar att fälten verkligen är ifyllda och att en korrekt epostadress används.


 

Förutsättningar för att följa guiden

För att du ska kunna följa denna guide förutsätter vi att du har grundkunskaper i PHP motsvarande guiden PHP grunder » och PHP fortsättning »

OBS! Om du inte konfigurerat och använder din egen dator som webbserver med mailfunktionerna aktiverade kan du INTE testa dina PHP-sidor lokalt. Du måste då publicera och testa filerna online på din webbserver med PHP-stöd när du använder exemplen i denna guide.

För att mailfunktionerna i PHP ska fungera måste din webbserver ha tillgång till ett mailprogram som tex Sendmail, Qmail eller Postfix.

Kolla din PHP-info om din webbserver online (inte den lokala webbservern) har sökvägen (Path) angiven till Sendmail:

 

TIPS! Om du får problem med att använda exemplen i den här guiden kanske du hittar en lösning i guiden Felsökning i PHP och MySQL »

 

Skicka mail med funktionen MAIL i PHP

Att skicka mail med PHP är relativt enkelt när du använder funktionen MAIL där du anger mottagarens e-postadress, ämnesrubrik (subject) och meddelandetext som parametrar:

<?php

mail("your@adress.com", "
Ämne här", "Meddelandetexten här");

?>

Testa gärna din mailfunktion med koden ovan!

Spara dokumentet med namnet "mail.php"

Ange din egen e-postadress och kör filen på din webbserver online. Om du får mailet i ditt vanliga epost-program så ser du att mailfunktionerna är korrekt installerade.

Läs mer om funktionen MAIL hos PHP.net

 

Formulär för att skicka meddelandet

Du kan använda ett vanligt formulär för att skicka informationen direkt till en e-postmottagare.

I exemplet nedan används två PHP-dokument, ett för formuläret och ett för koden som bearbetar innehållet i formuläret.

Den sida som bearbetar formulärdatan fungerar också som en bekräftelsesida där den skickade informationen visas.

Läs mer om formulär i guiden PHP fortsättning »

OBS! Exemplet fungerar bara som en introduktion till formulärscript och du kan alltså testa det själv men bör inte använda det i skarpt läge" innan du validerat uppgifterna enligt nästa avsnitt.

 

Skapa ditt formulär i en fil med namnet "kontaktform.php".

Här är koden till formuläret:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Kontakta oss</title>
</head>
<body>

<h2>Kontakta oss </h2>

<form id="kontakt" name="kontakt" method="post" action="formmail.php">
<label for="fnamn">Förnamn:</label><br>
<input type="text" name="fnamn" id="fnamn"><br>
<label for="enamn">Efternamn:</label><br>
<input type="text" name="enamn" id="enamn"><br>
<label for="email">E-postadress:</label><br>
<input type="text" name="email" id="email"><br><br>
<textarea name="message" cols="30" rows="5"></textarea><br><br>
<input name="submit" type="submit"
value="Skicka meddelandet">
</form>

</body>
</html>

Klicka här för att se hela koden till "kontaktform.php"

 

PHP-kod som bearbetar innehållet i formuläret

Filen som formuläret anropar och som bearbetar det innehåll som skickats med formuläret är "formmail.php".

Filen "formmail.php" sparar informationen från formulärfältet som variabler. I den första variabeln $to anger du e-postadressen till mottagaren. De övriga variablerna hämtar den information som anges i formulärfälten.

Detta exempel använder HEADERS för att ange MIME-typ för den aktuella filen. Här anges också vilken teckenuppsättning som ska användas.

Exemplet använder charset=utf-8 som tillåter användning av ÅÄÖåäö och specialtecken. Läs mer om teckenuppsättningar i guiden Teckenkoder - charset »

Läs mer om HEADER hos PHP.net
Läs mer om MIME hos Wikipedia

I funktionen MAIL anges som de tre första parametrarna de variabler som innehåller uppgifterna för mottagare, ämnesrubrik och meddelande. Den fjärde parametern i funktionen MAIL kan användas för meddelandets huvud (message header), mer om detta i avsnitten nedan.

De uppgifter som angivits i formuläret skrivs ut med funktionen ECHO och för radbrytning används funktionen NL2BR (läs mer om radbrytning i guiden PHP fortsättning  »).

Skapa en fil med namnet "formmail.php".

Här är koden till "formmail.php":

<?php

$to = "din_egen@e-postadress_här";
$from = $_POST["email"];
$subject = 'Kontakt från webbplatsen!';
$fnamn = $_POST["fnamn"];
$enamn = $_POST["enamn"];
$message = $_POST["message"];

##########################
// HEADERS för innehållstyp och textkodning

$headers = "Content-Type: text/plain; charset=utf-8 \r\n";
$headers .= "From:".$fnamn." ".$enamn." <".$from.">"."\r\n";
$headers .= "MIME-Version: 1.0 \r\n";
###########################

// Konverterar ÅÄÖåäö till UTF-8
$subject='=?UTF-8?B?'.base64_encode($subject).'?=';

// Mailfunktionen som skickar bekräftelsen
if (mail($to, $subject, $message, $headers))

echo nl2br("<h2>Ditt meddelande har skickats!</h2>
<b>mottagare:</b> $to
<b>meddelande:</b>
$message
");

else
echo "Det gick inte att skicka ditt meddelande";
}

?>

Klicka här för att se hela koden till "formmail.php"

Prova att skriva in information i alla fält i ditt formulär. I exemplet nedan har information skrivits i fälten "fnamn", "enamn", "email" och "message". Det är samma namn som används till variablerna i koden ovan och informationen lagras i de angivna variablerna:

När formuläret skickats skrivs informationen ut som en bekräftelse:

Kolla mailet i ditt e-postprogram:

 

Enkel validering av formuläret

Validering av innehållet i formuläret är viktigt!

Det finns en risk att ditt formulär och ditt formmail-script blir spammat av någon spambot (spam robot). Anledningar till att spamma formulär är desamma som att spamma e-postadresser, målet är att sprida annonser och andra "erbjudanden". Dessutom vill spammarna lägga ut sina länkar (URL) i forum, gästböcker och bloggar för att hamna högre i rankingen hos sökmotorer som tex Google.

Du kan inte stoppa spam till 100% men du kan utföra åtgärder som minskar attackerna. En vanlig metod idag är att använda en verifieringsbild istället för vanlig text, en sk Captcha (robotfälla) vid inloggning till olika tjänster. Captchas används nu tyvärr även av spammare för att förhindra att ditt antispamprogram använder OCR för att hitta textinformation som är vanlig i spam. Läs mer om Spambots  och Captcha  hos Wikipedia.

Läs mer i guiden Formmail med CAPTCHA » om hur du kan använda dina egna captcha i ditt formulär.

Du kan validera ditt formulär med de två metoderna clientside och serverside.

När du validerar clientside används vanligen Javascript som direkt i webbläsaren kontrollerar innehållet i formuläret. Den här metoden är ibland snabbare än att använda serverside validering med PHP eftersom ingen information skickas mellan användaren och webbservern när valideringen genomförs. Nackdelen med Javascript är att vissa användare stängt av användning av Javascript i sin webbläsare och att olika webbläsare kan behandla koden olika. Validering serverside med PHP är en säkrare metod och du kan använda båda metoderna för att säkerställa att någon av valideringarna genomförs.

Vi har valt att använda validering serverside med PHP. I det här avsnittet visas hur du kan använda en enkel validering för att kontrollera att innehåll har angivits i de formulärfält du vill att användaren ska fylla i innan formuläret skickas. Här kontrolleras inte om innehållet är korrekt och att giltiga e-postadresser och URL:er angivits och detta visas istället i nästa avsnitt.

Vi placerar koden som kontrollerar om information angivits i formulärfälten i "formmail.php" (samma dokument som bearbetar formuläret).

Fältnamn som inte är ifyllda sparas här i en variabel med namnet $errors och placeras i en array. De eventuella fel som sparats i vektorn skrivs ut med funktionen FOREACH och visas tillsammans med texten du angivit. För att användaren inte ska behöva backa med webbläsarens "bakåt-knapp" har vi lagt till:
javascript:history.go (-1)

Här är koden till "formmail.php":

<?php

// anger en variabel som kan lagra de eventuella felaktigheterna
$errors = array();

// kontrollera om ett Förnnamn angivits
if (!$_POST["fnamn"])
$errors[] = "- FÖRNAMN";

// kontrollera om ett Efternamn angivits

if (!$_POST["enamn"])
$errors[] = "- EFTERNAMN";

// kontrollera om en E-postadress angivits

if (!$_POST["email"])
$errors[] = "- E-POSTADRESS";

// kontrollera om ett Meddelande angivits

if (!$_POST["message"])
$errors[] = "- inget MEDDELANDE har skrivits!";

// om felaktig information finns visas detta meddelande

if (count($errors)>0){
echo "<strong>Följande information måste anges innan du kan skicka formuläret:</strong><br />";
foreach($errors as $fel)
echo "$fel <br />";
echo "<br />Ange den information som saknas och skicka formuläret igen. Tack! <br />";
echo "<a href='javascript:history.go(-1)'>klicka här för att komma tillbaka till formuläret</a>";
}

else {
// formuläret är korrekt ifyllt och informationen bearbetas
$to = "din_egen@e-postadress_här";
$from = $_POST["email"];
$subject = 'Kontakt från webbplatsen!';
$fnamn = $_POST["fnamn"];
$enamn = $_POST["enamn"];
$message = $_POST["message"];
####################

// HEADERS för innehållstyp och textkodning
$headers = "Content-Type: text/plain; charset=utf-8 \r\n";
$headers .= "From:".$fnamn." ".$enamn." <".$from.">"."\r\n";
$headers .= "MIME-Version: 1.0 \r\n";
####################
// Konverterar ÅÄÖåäö till UTF-8

$subject='=?UTF-8?B?'.base64_encode($subject).'?=';
// Mailfunktionen som skickar bekräftelsen
if (mail($to, $subject, $message, $headers))
echo nl2br("<h2>Ditt meddelande har skickats!</h2>
<b>mottagare:</b> $to
<b>meddelande:</b>
$message
");

else
echo "Det gick inte att skicka ditt meddelande";
}

?>

Klicka här för att se koden till exemplet ovan

 

Vi provar att skicka formuläret utan att ange en e-postadress och felmeddelandet visas tillsammans med en "tillbaka-länk":

Om formuläret skickas helt tomt visas alla felmeddelanden enligt vår validering:

 

Validering av e-postadresser med PREG_MATCH

Den enkla valideringen i avsnittet ovan kan vara tillräcklig om du bara vill säkerställa att vissa fält verkligen är ifyllda. Om du däremot har behov av att den angivna informationen verkligen är korrekt kan du använda regular expressions (reguljära uttryck).

I detta avsnitt visas hur du använder reguljära uttryck för att kontrollera att e-postadresser är giltiga. Ett reguljärt uttryck (regular expression) eller ibland förkortat till regexp eller regex är en metod för att matcha komplexa strängars mönster som tex en e-postadress.

Det finns flera funktioner i PHP som använder reguljära uttryck och vi kommer att använda PREG_MATCH (perform a regular expression match) för att ange ett mönster som epostadresser måste följa för att vara giltiga.

Läs mer om PREG_MATCH hos PHP.net

 

TIPS! Regular expressions är ett stort område som egentligen kräver en egen guide. Om du är intresserad av att lära dig mer kan du göra det hos:
http://www.regular-expressions.info

Där finns det även finns ett avsnitt som anknyter till vårt exempel om e-postadresser: http://www.regular-expressions.info/email.html

 

Förts kontrollen av en e-postadress kan göras genom att validera om tecknet @ finns angivet.

Nästa steg är att kontrollera uppbyggnaden av e-postadressen som ofta är name@domain.suffix vilket i vårt exempel är lisa@dromvavaren.se men i verkligheten skulle kunna vara andra varianter:

lisa@drömvavaren.se
lisa@dromvavaren.com
lisa@inkop.dromvavaren.se
lisa@inköp.drömvavaren.se
lisa.johansson@dromvavaren.se
lisa_johansson@dromvavaren.se
lisa@dromvavaren.org.uk

Idag kan ju även åäö och vissa andra sk "specialtecken" användas och även toppdomänerna som förut var två eller tre tecken som tex: .SE .COM .NET kan idag vara upp till sex tecken då nya toppdomäner tillkommit som tex .MUSEUM .INFO .TRAVEL .JOBS .MOBI mfl.

Dessutom finns förslag på att domännamn som förut bara använde ASCII-tecken ska kunna innehålla Internationalized Domain Names (IDNs) som använder lokala teckenuppsättningar specifikt för olika länder och språk som tex arabiska och kinesiska.

Som du förstår är det omöjligt att ange ett reguljärt urtryck som innefattar alla kombinationer av domännamn med de olika specialtecken som finns.

Om du anger ett mönster som är FÖR specifikt kan du utestänga många e-postadresser och om du istället anger ett för allmänt mönster kommer ogiltiga e-postadresser att kunna användas medvetet eller omedvetet av avsändaren.

Det viktiga är ju att en kontroll sker av att e-postadressen kan vara giltig än att verifiera att den verkligen finns. Du undviker då förhoppningsvis att användaren av misstag anger en felaktig adress men hindrar inte spambots från att spamma ditt formulär.

OBS! Exemplet nedan är ett förslag på REGEXP men du bör vara medveten om att den inte till 100% täcker alla toppdomäner, specialtecken, lokala teckenuppsättningar och kombinationer av användarnamn.

Du kan inte heller vara säker på att mailprogrammet ( Sendmail, Qmail, Postfix eller annat) verkligen klarar av de tecken som e-postadressen innehåller. Även om tecknen åäöÅÄÖ är tillåtna i svenska domännamn idag så fungerar de inte i alla webbläsare och inte heller i alla mailprogram.

 

Exemplet nedan visar verifiering av e-postadress där adressen hämtats från formuläret i vårt tidigare exempel och sparats i variabeln $emailcheck för att sedan matchas mot det reguljära uttrycket som angivits i funktionen PREG_MATCH:

// kontrollera om en e-postadress angivits
$emailcheck = $_POST["email"];

preg_match("/^[a-z0-9\å\ä\ö._-]+@[a-z0-9\å\ä\ö.-]+\.[a-z]{2,6}$/i", $emailcheck))

Om vi tittar närmare på vad uttrycket innebär (och tar bort åäö i mönstret) så är exemplet:

/^[a-z0-9._-]+@[a-z0-9.-]+\.[a-z]{2,6}$/i

 

Tecknen A-Z och siffrorna 0-9 är enkla att förstå men de övriga tecknen förklaras här:

/ början och slut på mönstret
^ matcha från start av strängen
$ matcha från slutet av strängen
[] matcha någon av tecknen inom hakparentesen
+ antal tecken som matchas. Plustecken betyder "1 eller fler".
* antal tecken som matchas. Asterisk betyder "0 eller fler".
{2} antal tecken som matchas (exakt 2)
{2,6} antal tecken som matchas (minst 2 och högst 6)
i anger att de angivna tecknen matchas både versalt och gement (OBS! viktigt i vårt exempel). Om inte "i" anges så måste både versaler och gemener av de angivna tecknen anges. Exemplet a-z0-9\å\ä\ö ändras till a-zA-Z0-9\å\Å\ä\Ä\ö\Ö

Om vi delar upp koden i tre delar så blir det tydligare vad varje uttryck egentligen gör.

PREG_MATCH Del 1:

[a-z0-9._-]+@

Den del av epostadressen som anges före @ måste innehålla minst ETT tecken (+) som då kan vara bokstäver mellan a-z och siffror mellan 0-9 samt punkt (.) underscore (_) och bindestreck (-).

Inledningen av e-postadressen kan då vara:

lisa@       _lisa@       lisa64@       64-lisa@       lisa.johansson@       lisa_johansson@

PREG_MATCH Del 2:

[a-z0-9.-]+\.

Den del av e-postadressen som anges efter @ måste innehålla minst ETT tecken (+) enligt ovan men måste avslutas med en punkt (här anges en backslash som escape-tecken för att ange att punkten inte är en del av koden utan är just tecknet "punkt").

Fortsättningen på e-postadressen kan då vara:

dromvavaren.       inkop.dromvavaren.      inkop-dromvavaren.

PREG_MATCH Del 3:

[a-z]{2,6}$/i

Den sista delen av e-postadressen efter det obligatoriska punkt-tecknet. Måste innehålla minst 2 och högst 6 tecken som bara får vara bokstäverna a-z . Notera även bokstaven "i" som ju anger att både VERSALER och gemener omfattas.

Den sista delen av e-postadressen kan då vara:

se    com   info    museum     net    uk    org.uk

 

Validering serverside med PREG_MATCH

Lägg till validering serverside med funktionen PREG_MATCH i vårt formmail-exempel enligt nedan.

Vi placerar koden som validerar e-postadressen i "formmail.php" och ersätter kodavsnittet där vi tidigare hade den enkla valideringen av e-postadressen:

//mer kod ovan...

// kontrollera om ett Efternamn angivits

if (!$_POST["enamn"])
$errors[] = "- EFTERNAMN";

// kontrollera om en korrekt E-postadress angivits

$emailcheck = $_POST["email"];
if(!preg_match("/^[a-z0-9\å\ä\ö._-]+@[a-z0-9\å\ä\ö.-]+\.[a-z]{2,6}$/i", $emailcheck))
$errors[] = "- din E-POSTADRESS saknas eller är felaktig";


// kontrollera om ett Meddelande angivits
if (!$_POST["message"])
$errors[] = "- inget MEDDELANDE har skrivits!";

//mer kod nedan...

Klicka här för att se hela koden till exemplet

 

Om du vill lägga till fler specialtecken än åäö använder du backslash som escape-tecken före varje nytt tecken:

/^[a-z0-9\å\ä\ö\ü\%._-]+@[a-z0-9\å\ä\ö\ü\%.-]+\.[a-z]{2,6}$/i

 

Här är vårt exempelformulär (som nu formaterats med CSS) där en korrekt e-postadress nu är angiven och inget felmeddelande bör visas när det skickas:

Klicka här för att se hela koden till exemplet "kontaktform.php"

 

Om en epostadress som INTE matchar mönstret i PREG_MATCH visas istället vårt felmeddelande:

Testa valideringen i formuläret i början av denna guide och prova att ange korrekta och ogiltiga epostadresser!

 

HTTP_REFERER för kontroll av Formmail

Problemet med spambots kan du minska genom att använda funktionen HTTP_REFERER som kontrollerar att "formmail.php" hämtar uppgifterna från just ditt formulär.

HTTP_REFERER hämtar URL:en för den sida som skickar information eller länkar vidare till den aktuella sidan och det är webbläsaren som lagrar informationen (clientside istället för serverside).

OBS! Vissa webbläsare använder inte HTTP_REFERER och brandväggar kan vara inställda på att inte acceptera referers. Användaren kan dessutom själv stänga av funktionen (detsamma gäller ju Javascript) och detta är alltså inte en helt tillförlitlig metod men kan vara ett bra alternativ till att få formuläret spammat.

Om du får problem med spam i dina formulär kan du använda HTTP_REFERER tillfälligt under en period och sedan ta bort funktionen.

Här används HTTP_REFERER för att kontrollera om "formmail.php" anropats från formuläret "kontaktform.php".

Observera att en URL kan anges med eller utan "www" och i exemplet anges båda alternativen:

//kontrollera om scriptet anropas från ditt formulär
if (($_SERVER['HTTP_REFERER']!= "http://www.dinadress.se/kontaktform.php")  
&& ($_SERVER['HTTP_REFERER']!= "http://dinadress.se/kontaktform.php")) { 
$errors[] = "- din användning av vårt Formmail är inte tillåten!"; 
}

Klicka här för att se hela koden till exemplet

 

Om "formmail.php" anropas direkt i webbläsaren (utan att ditt formulär används) visas att scriptet anropats på ett felaktigt sätt:

Testa din HTTP_REFERER genom att stänga och öppna webbläsaren på nytt och skriv in adressen direkt till ditt formmail-script tex:

"http://www.dinadress.se/kontaktform.php"

Ditt felmeddelande ska då visas om din webbläsare tillåter referers.

 

SESSIONS för kontroll av Formmail

En annan metod för att minska spam är att använda sessioner som kontrollerar att "formmail.php" hämtar uppgifterna från ditt formulär.

Läs mer om sessioner i guiden PHP fortsättning »

Den här metoden startar en session i "kontaktform.php" som lagrar innehållet i den globala variabeln $_SESSION och i "formmail.php" kontrolleras om variabeln finns eller ej.

Koden som startar sessionen i "kontaktform.php" måste anges FÖRE all annan kod.

Här anges innehållet i variabeln $_SESSION till "yes" och kontrolleras i scriptet. Du kan ange vad som helst som värde bara du använder samma värde i "formmail.php":

<?php

//starta sessionen
session_start();
$_SESSION["form_session"] = "yes";

?>


//mer kod nedan..

Klicka här för att se hela koden till "kontaktform.php"

 

Sessionen måste startas även i "formmail.php" och då FÖRE all annan kod. Kontroll sker med funktionen ISSET om variabeln $_SESSION har samma innehåll som i "kontaktform.php". Alla startade sessioner stängs i slutet av koden:

<?php
//starta sessionen
session_start();
?>


//övrig kod startar här...

//kontrollerar om en session är aktiv
if (!isset ($_SESSION["form_session"]))
$errors[] = "
- din användning av vårt Formmail är inte tillåten!";

//mer kod här..

//Stänger sessionen
session_unset();
session_destroy();


?>

Klicka här för att se hela koden till "formmail.php"

 

Testa din session genom att fylla i formuläret och skicka det som vanligt:

Uppdatera webbläsaren med F5 för att köra scriptet igen och starta sessionen på nytt men nu bara i "formmail.php":

Nu visas felmeddelandet då sessionen inte innehåller $_SESSION["form_session"]:

 

STRIPSLASHES

PHP använder tecknet backslash \ som escape-tecken även framför själva tecknet backslash \.

Om du skriver en sökväg i vårt formulärexempel som tex:

C:\www\dromvavaren\index.php

Funktionen STRIPSLASHES kan användas för att ta bort de extra backslashes som PHP eventuellt lägger till.

Läs mer om STRIPSLASHES hos PHP.net

I exemplet nedan används backslash i fältet "Meddelande":

Så här kan bekräftelsen se ut:

TIPS! Du kan skydda ditt formulär mot spamrobotar genom att använda en "captcha" - läs mer i guiden Formmail med CAPTCHA »

 

Felsökning om det inte fungerar

Om du får problem med användning av PHP Mail kan du läsa mer i guiden Felsökning i PHP och MySQL »

 

Formmail - hämta färdiga mallar och exempel

Hämta mallarna i guiden Formmail - färdiga mallar »

Mallar som använder funktionen MAIL för att skicka formulärdata till en e-postadress.

Formulären kontrolleras med validering av att formulärfälten är ifyllda och validering av epostadresser sker med PREG_MATCH och REGEXP.

Exemplen innehåller även HTTP_REFERER som en kontroll av att Formmail skickas från just ditt formulär.