A simple PHP mail contact form with MySQL


Welcome to the first PHP tutorial on TheTechLabs.com. In this tutorial I’m gonna show you how to make a simple php contact form for any website, sending the info by mail and saving it on a MySQL DataBase. This tutorial will be like an intro to a more detailed and complex series of php articles that in the end will result on the interaction of php and flash in a cms system. Hope you enjoy the tutorial.

Requirements

  • A text editor to edit php, it’s not necessary a professional editor, with NotePad or NotePad++ it’s ok
  • A PC with XAMPP or other web server with PHP support installed, or access to a PHP web server
  • Access to the phpMyAdmin
  • Access to a MySQL data base
  • Download the source files

Pre-Requesites

  • Basic PHP knowledge
  • HTML forms knowledge

Database structure

Our first step it’s define our Data Base structure. In this case in particular we gonna have fields from the data entered by the user and automatic server data, as the ip address, so we could track some additional info of the user. So our database must looks something like

  • id
  • name
  • email
  • url
  • comment
  • date
  • ip

Create the Database

For this step we could use the phpMyAdmin interface to create the data base or use the SQL file provided in the tutorial

  • id – integer with size 11 and auto increment used as index of the table
  • name – Varchar with 100 chars, it can’t be null
  • email – Varchar with 100 chars, it can’t be null
  • url – Varchar with 200 chars
  • comment – Text
  • date – DateTime
  • ip – – Varchar with 255 chars

Or just run the script on the phpMyAdmin SQL section:

CREATE TABLE IF NOT EXISTS `contacts` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(100) NOT NULL,
  `email` varchar(100) NOT NULL,
  `url` varchar(200) default NULL,
  `comment` text,
  `date` datetime NOT NULL,
  `ip` varchar(255),
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

The form

Our form gonna have 3 input fields and 1 text area:

  • Name
  • Email
  • Website url
  • Comment

So, now we could start with the form. The action gonna pass the data to itself via POST, so we gonna need and additional hidden field called action, so when the data it’s submitted, we check that variable to know if something it’s sent and act accordingly.

<form id="contact" name="contact" action="contact.php" method="post">

<p><label>Name: <input type="text" id="name" name="name" value="" /></label></p>

<p><label>Email: <input type="text" id="email" name="email" value="" /></label></p>

<p><label>Website: <input type="text" id="url" name="url" value="http://" /></label></p>

<p><label>Comment:<br /><textarea id="comment" name="comment"></textarea></label></p>

<input type="hidden" id="action" name="action" value="submitform" />

<p><input type="submit" id="submit" name="submit" value="Submit" /> <input type="reset" id="reset" name="reset" value="Reset" /></p>

</form>

Now our form must looks something like this one:

Notice the hidden input with the action id, it have the submitform value, this gonna help us to determine if we save the data or not

The data base connection

Now we have to define a data base connection before we could save the data, we gonna need the login, the password and the name of the database. So, in a new file called connection.php we define the new connection, this is because we probably gonna re use the connection in other pages, it’s better define it in a file we could include later in any php page.

$hostname = "localhost";
$database = "db_contacts";
$username = "root";
$password = "back2skl";
$connection = mysql_connect($hostname, $username, $password) or trigger_error(mysql_error(),E_USER_ERROR);

The additional functions

When we work with databases, it’s quite possible we have serious security problems. One of the most common attacks it’s the SQL injection, one way to avoid SQL injections is sanitize the data we enter on a form, this function cast the different values we enter and return teh right type, so if someone enter a SQL command to delete the data on the database, the command gonna be stored as text and don’t gonna execute

function sanitize($value, $type)
{
  $value = (!get_magic_quotes_gpc()) ? addslashes($value) : $value;

  switch ($type) {
    case "text":
      $value = ($value != "") ? "'" . $value . "'" : "NULL";
      break;
    case "long":
    case "int":
      $value = ($value != "") ? intval($value) : "NULL";
      break;
    case "double":
      $value = ($value != "") ? "'" . doubleval($value) . "'" : "NULL";
      break;
    case "date":
      $value = ($value != "") ? "'" . $value . "'" : "NULL";
      break;
  }

  return $value;
}

Notice that we use the PHP function add slashes before we enter to the switch, in this way we have a string with backslashes before characters that need to be quoted in database queries, the we enter ans set the type of data we need according to the type

Recieving the data

Now we include the connection file and check if there’s something to save and send by mail, all at the beginning of the contact file.

//include the connection file

require_once('connection.php');

//save the data on the DB and send the email

if(isset($_POST['action']) && $_POST['action'] == 'submitform')
{
	//recieve the variables

	$name = $_POST['name'];
	$email = $_POST['email'];
	$url = $_POST['url'];
	$comment = $_POST['comment'];
	$ip = gethostbyname($_SERVER['REMOTE_ADDR']);
}

We use another PHP function to get the ip of the visitor using the gethostbyname($_SERVER['REMOTE_ADDR'])

Saving data

So, by now we received the data from our form, now we gonna save the data on our data base

//save the data on the DB

mysql_select_db($database, $connection);

$insert_query = sprintf("INSERT INTO contacts (name, email, url, comment, date, ip) VALUES (%s, %s, %s, %s, NOW(), %s)",
						sanitize($name, "text"),
						sanitize($email, "text"),
						sanitize($url, "text"),
						sanitize($comment, "text"),
						sanitize($ip, "text"));

$result = mysql_query($insert_query, $connection) or die(mysql_error());

So, we select our data base, then we make the query and put it on a variable to make the mysql_query or stop if somethings go wrong. Notice two things, first we are using the MySQL NOW(); function for the dateTime field and we are sanitizing each variable we enter on the data base.

Sending email

So, if everything goes fine, we gonna have something like this in our phpMyAdmin

Now we could send an email to the interested person, like the webmaster, about the new comment on the website

if($result)
{
	//send the email

	$to = "[email protected]";
	$subject = "New contact from the website";

	//headers and subject
	$headers  = "MIME-Version: 1.0rn";
	$headers .= "Content-type: text/html; charset=iso-8859-1rn";
	$headers .= "From: ".$name." <".$email.">rn";

	$body = "New contact
";
	$body .= "Name: ".$name."
";
	$body .= "Email: ".$email."
";
	$body .= "Comment: ".$comment."
";
	$body .= "IP: ".$ip."
";

	mail($to, $subject, $body, $headers);

	//ok message

	echo "Your message has been sent";
}

First we check if php insert the data on the data base, then we set who receives and the subject of the email, then we set the headers of the email, so it could be delivered as html, and finally we compose the email. all the code must looks something like this

//include the connection file

require_once('connection.php');

//save the data on the DB and send the email

if(isset($_POST['action']) && $_POST['action'] == 'submitform')
{
	//recieve the variables

	$name = $_POST['name'];
	$email = $_POST['email'];
	$url = $_POST['url'];
	$comment = $_POST['comment'];
	$ip = gethostbyname($_SERVER['REMOTE_ADDR']);

	//save the data on the DB

	mysql_select_db($database, $connection);

	$insert_query = sprintf("INSERT INTO contacts (name, email, url, comment, date, ip) VALUES (%s, %s, %s, %s, NOW(), %s)",
							sanitize($name, "text"),
							sanitize($email, "text"),
							sanitize($url, "text"),
							sanitize($comment, "text"),
							sanitize($ip, "text"));

	$result = mysql_query($insert_query, $connection) or die(mysql_error());

	if($result)
	{
		//send the email

		$to = "[email protected]";
		$subject = "New contact from the website";

		//headers and subject
		$headers  = "MIME-Version: 1.0rn";
		$headers .= "Content-type: text/html; charset=iso-8859-1rn";
		$headers .= "From: ".$name." <".$email.">rn";

		$body = "New contact
";
		$body .= "Name: ".$name."
";
		$body .= "Email: ".$email."
";
		$body .= "Comment: ".$comment."
";
		$body .= "IP: ".$ip."
";

		mail($to, $subject, $body, $headers);

		//ok message

		echo "Your message has been sent";
	}
}

function sanitize($value, $type)
{
  $value = (!get_magic_quotes_gpc()) ? addslashes($value) : $value;

  switch ($type) {
    case "text":
      $value = ($value != "") ? "'" . $value . "'" : "NULL";
      break;
    case "long":
    case "int":
      $value = ($value != "") ? intval($value) : "NULL";
      break;
    case "double":
      $value = ($value != "") ? "'" . doubleval($value) . "'" : "NULL";
      break;
    case "date":
      $value = ($value != "") ? "'" . $value . "'" : "NULL";
      break;
  }

  return $value;
}

Well, that’s all, now you could make your own PHP forms, knowing how to add or remove fields, remember to do the same with the data base. Hope you find this tutorial usefull, and thanks for read.


Did you enjoy this article?
Share the love
Get free updates and win TTL prizes

Other Posts You Might Like

42 Responses to “A simple PHP mail contact form with MySQL”

  1. Zipper says:

    Why not using mysql_real_escape() instead of your own sanitize() method? And “magic quotes” are quite outdated and should not be used anymore.
    Additionally you should also escape the request parameters in the mail text (header) otherwise it is vulnerable for spammers.

  2. johnny says:

    this is a joke?!

  3. Fausto Carrera says:

    @Zipper mysql_real_escape_string is used just for strings. Other function could be:

    // Quote variable to make safe
    function quote_smart($value)
    {
    // Stripslashes
    if (get_magic_quotes_gpc()) {
    $value = stripslashes($value);
    }
    // Quote if not a number or a numeric string
    if (!is_numeric($value)) {
    $value = “‘” . mysql_real_escape_string($value) . “‘”;
    }
    return $value;
    }

    And yeah, you are right, I missed the mysql_real_escape_string on the text cast.

  4. uniquelasvegastravel says:

    Keep working ,great job!

  5. Forget Gurus says:

    Hey, this is an excellent post, I really enjoyed the content. Please don’t stop I look forward to reading more!

  6. Bekir Arslan says:

    Thanks very much fot that nice tutorial. It was very helpful

  7. katie says:

    The source files are missing! where can i download them? can you re-post them?

  8. Carlos Pinho says:

    @katie

    Thank you for pointing the broken link. I’ve fixed it, you can now download the source files.

  9. David says:

    Hi.

    I’m a PHP noob.

    Can you embed this form in an existing XHTML page? If not, how do you place the PHP code in a PHP page without the page displaying the code?

    When I preview “contact.php” on a web server, I see:

    \r\n”; $body = “New contact
    “; $body .= “Name: “.$name.”
    “; $body .= “Email: “.$email.”
    “; $body .= “Comment: “.$comment.”
    “; $body .= “IP: “.$ip.”
    “; mail($to, $subject, $body, $headers); //ok message echo “Your message has been sent”; } } function sanitize($value, $type) { $value = (!get_magic_quotes_gpc()) ? addslashes($value) : $value; switch ($type) { case “text”: $value = ($value != “”) ? “‘” . $value . “‘” : “NULL”; break; case “long”: case “int”: $value = ($value != “”) ? intval($value) : “NULL”; break; case “double”: $value = ($value != “”) ? “‘” . doubleval($value) . “‘” : “NULL”; break; case “date”: $value = ($value != “”) ? “‘” . $value . “‘” : “NULL”; break; } return $value; } ?>

    above the form.

    Any help is much appreciated.

    Thanks.

  10. dVargas says:

    Great tutorial. It’s just what I needed

  11. Rah says:

    Whats the easiest way to add validation for required fields to this script?

  12. Balaji says:

    I am new user to php and mysql and just i did everything as you are mentioned and i am using wamp in desktop and i get the following error and will you clarify me please?.

    error
    Warning: mail() [function.mail]: Failed to connect to mailserver at “localhost” port 25, verify your “SMTP” and “smtp_port” setting in php.ini or use ini_set() in C:\Program Files\wamp\www\form\contact.php on line 49

  13. Pluplus says:

    Hi,

    Your script is so simple and clean, excellent work, just what I was looking for!

    Thanks a lot,

    J

  14. alan richards says:

    Excellent article, I enjoy every article I read here. Thanks,
    and keep bloggin!

  15. Sue says:

    Thanks a lot for your help!

  16. Sue says:

    Hi,
    I have created an email subscription form with your help also using captcha.

    you can see it at
    http://www.apple.renaissance.co.nz/RenPUB_junechanges/subform2.php

    It goes to verify2.php to sanitize and validate the captcha.

    Your form just sanitizes the email, can you please help with some validation options?

    Also when I put in the captcha values and submit the form, it gives the error — Column ‘email’ cannot be null (verify2.php) — I don’t know how to modify this error

    Here is my verify2.php script

    ==============

    is_valid) {
    die (header (“Location: sorry.html”) .
    “(reCAPTCHA said: ” . $resp->error . “)”);

    //die (“The reCAPTCHA wasn’t entered correctly. Go back and try it again.” . “(reCAPTCHA said: ” . $resp->error . “)”);

    }

    //include the connection file

    require_once(‘connection.php’);

    //save the data on the DB and send the email

    if(isset($_POST['action']) && $_POST['action'] == ‘submitform’)
    {
    //recieve the variables

    $email = $_POST['email'];
    $ip = gethostbyname($_SERVER['REMOTE_ADDR']);

    //save the data on the DB

    mysql_select_db($database_connection, $connection);

    $insert_query = sprintf(“INSERT INTO contacts (email, date, ip) VALUES ( %s, NOW(), %s)”,

    sanitize($email, “text”),
    sanitize($ip, “text”));

    $result = mysql_query($insert_query, $connection) or die(mysql_error());

    if($result)
    {
    //send the email

    $to = “[email protected]”;
    $subject = “New contact from the website”;

    //headers and subject
    $headers = “MIME-Version: 1.0\r\n”;
    $headers .= “Content-type: text/html; charset=iso-8859-1\r\n”;
    $headers .= “From: “.$email.”>\r\n”;

    $body = “New contact for ren corp”;
    $body .= “Email: “.$email.”";
    $body .= “IP: “.$ip.”";

    mail($to, $subject, $body, $headers);

    //ok message
    header(“Location: thanks.html”);

    //echo “   Thanks, you are added to our database!”;
    }
    }

    function sanitize($value, $type)
    {
    $value = (!get_magic_quotes_gpc()) ? addslashes($value) : $value;

    switch ($type) {
    case “text”:
    $value = ($value != “”) ? “‘” . $value . “‘” : “NULL”;
    break;
    case “long”:
    case “int”:
    $value = ($value != “”) ? intval($value) : “NULL”;
    break;
    case “double”:
    $value = ($value != “”) ? “‘” . doubleval($value) . “‘” : “NULL”;
    break;
    case “date”:
    $value = ($value != “”) ? “‘” . $value . “‘” : “NULL”;
    break;
    }

    return $value;
    }

    ?>

    ==========

    Can you please help as I am a php noob?

    Thanks in advance!

    Sue

  17. Josef Telmer says:

    It’s a very interesting subject I was looking around about more information but you got really what i was looking for in your article so thanks and keep it up you have a great blog .
    I’m very interested in CMS and all its related subjects.

  18. I’ve recently started a blog, the information you provide on this site has helped me tremendously. Thank you for all of your time & work.

  19. Parser5 says:

    Hi

    Would it be possible to add FILE and IMAGES to mysql database?
    Or is it perhaps better just to add the URL to get acess to it?

    Best regards!

    Alex

  20. Guy Ueland says:

    Your form does not work! I have tried it on my server and it does not post or email.

  21. Luis says:

    Gracias, me sirvio mucho y complemento mis conocimientos, en especial sobre la IP, Mil gracias.

  22. Edra Trelles says:

    Hi – It’s good to find such interesting stuff on the Internet as I have been able to fiind here. I agree with much of what is written here and I’ll be coming back to this site again. Thanks again for posting such great reading material!!

  23. lim says:

    I am new user to php and mysql and just i did everything as you are mentioned and i am using wamp in desktop and i get the following error and will you clarify me please?.

    error
    Warning: mail() [function.mail]: Failed to connect to mailserver at “localhost” port 25, verify your “SMTP” and “smtp_port” setting in php.ini or use ini_set() in C:\Program Files\wamp\www\form\contact.php on line 49

  24. It sounds like you’re producing complications yourself by wanting to solve this issue instead of looking at why their is often a problem inside initial position.

  25. Joy says:

    Really nice tutorial for a secure contact form. I didn’t find beter till now!
    Keep up the good work!

  26. Chris J. says:

    Thanks for this very helpful tutorial! I really needed this one for a simple forum that I am creating.

    Thank you very much!

  27. Dennis Riley says:

    Hi
    worked brilliantly for me, but instead of sending a confirmation email how would I redirect to another page please.

  28. Schedule says:

    You you could make changes to the post name How-to create a simple PHP mail contact form with MySQL – The Tech Labs to more better for your webpage you make. I liked the blog post nevertheless.

  29. Edward says:

    Can’t anyone then just look at the included connection file, know the database information, make up their own form and attack the database? I’m not understanding how the connection information is secured? Is there a particular chmod value that would allow the form page to use the connection page but not allow an attacker to view/download it?

  30. Kasper says:

    I’ve followed your instructions and only made minor additions, so it would fit my needs, but now it neither sends nor posts anything, and it prints

    rn”; $body = “New contact
    “; $body .= “Companyname: “.$companyname.”
    “; $body .= “Contactperson: “.$contactperson.”
    “; $body .= “Email: “.$email.”
    “; $body .= “Comment: “.$comment.”
    “; $body .= “IP: “.$ip.”
    “; mail($to, $subject, $body, $headers); //ok message echo “Your message has been sent”; } } function sanitize($value, $type) { $value = (!get_magic_quotes_gpc()) ? addslashes($value) : $value; switch ($type) { case “text”: $value = ($value != “”) ? “‘” . $value . “‘” : “NULL”; break; case “long”: case “int”: $value = ($value != “”) ? intval($value) : “NULL”; break; case “double”: $value = ($value != “”) ? “‘” . doubleval($value) . “‘” : “NULL”; break; case “date”: $value = ($value != “”) ? “‘” . $value . “‘” : “NULL”; break; } return $value; } ?>

    as part of the visible output right above the form. What does it mean and how do I get rid of it?

  31. Nirav Mehta says:

    everything running as well good but when we submit form , that Entry showing on database but user and admin not getting emails

  32. Nirav Mehta says:

    everything running as well good but when we submit form , that Entry showing on database but user and admin not getting emails

  33. Mike Decastros says:

    thanks for your help your tutorial helps me a lot yepehhhhhhhhhhhhhhh i can now edit my website ^_^

  34. rogel says:

    can someone help me i dont understand how to connect the form to the database

  35. Irfs says:

    perfect! thanks for sharing your knowledge with the world.
    lots of kudos.

  36. mlee3680 says:

    Fantastic post. Here’s a tool that lets your build your online database without programming. There is no need to hand code PHP. Cut your development time by 90% http://www.caspio.com/

  37. A few words or warning here….

    1 – Setting ids in MySQL to unsigned will decrease the overhead used as they won’t require negative numbers.

    2 – Addslashes isn’t enough to prevent hacking. At the very least you should be using mysql_real_escape_string.

    3 – Just under “Recieving the data” you have a few raw $_POST variables which could all be exploited before sanitization.

    Apart from those small things, it’s a very informative article… Nice work ;)

  38. GoaMonitor says:

    where do i get good servers in toronto http://www.beatfunk.com
    .adslot-overlay {position: absolute; font-family: arial, sans-serif; background-color: rgba(0,0,0,0.65); border: 2px solid rgba(0,0,0,0.65); color: white !important; margin: 0; z-index: 2147483647; text-decoration: none; box-sizing: border-box; text-align: left;}.adslot-overlay-iframed {top: 0; left: 0; right: 0; bottom: 0;}.slotname {position: absolute; top: 0; left: 0; right: 0; font-size: 13px; font-weight: bold; padding: 3px 0 3px 6px; vertical-align: middle; background-color: rgba(0,0,0,0.45); text-overflow: ellipsis; white-space: nowrap; overflow: hidden;}.slotname span {text-align: left; text-decoration: none; text-transform: capitalize;}.revenue {position: absolute; bottom: 0; left: 0; right: 0; font-size: 11px; padding: 3px 0 3px 6px; vertial-align: middle; text-align: left; background-color: rgba(0,0,0,0.45); font-weight: bold; text-overflow: ellipsis; overflow: hidden; white-space: nowrap;}.revenue .name {color: #ccc;}.revenue .horizontal .metric {display: inline-block; padding-right: 1.5em;}.revenue .horizontal .name {padding-right: 0.5em;}.revenue .vertical .metric {display: block; line-height: 1.5em; margin-bottom: 0.5em;}.revenue .vertical .name, .revenue .vertical .value {display: block;}.revenue .square .metric, .revenue .button .metric {display: table-row;}.revenue .square .metric {line-height: 1.5em;}.revenue .square .name, .revenue .square .value, .revenue .button .value {display: table-cell;}.revenue .square .name {padding-right: 1.5em;}.revenue .button .name {display: block; margin-right: 0.5em; width: 1em; overflow: hidden; text-overflow: clip;}.revenue .button .name:first-letter {margin-right: 1.5em;}a.adslot-overlay:hover {border: 2px solid rgba(58,106,173,0.9);}a.adslot-overlay:hover .slotname {border-bottom: 1px solid rgba(81,132,210,0.9); background-color: rgba(58,106,173,0.9);}a.adslot-overlay:hover .revenue {border-top: 1px solid rgba(81,132,210,0.9); background-color: rgba(58,106,173,0.9);}div.adslot-overlay:hover {cursor: not-allowed; border: 2px solid rgba(64,64,64,0.9);}div.adslot-overlay:hover .slotname {border-bottom: 1px solid rgba(128,128,128,0.9); background-color: rgba(64,64,64,0.9);}div.adslot-overlay:hover .revenue {border-top: 1px solid rgba(128,128,128,0.9); background-color: rgba(64,64,64,0.9);}

  39. a6april says:

    How do I add a redirect on successful completion of the form

  40. damaki says:

    Does not work for me. Everything is ok, message inserts into database, and I get message “Your message has been sent”, but I never receice message on my mail. Please help me.

Leave a Reply

TTL VIP
Become a TTL VIP Member & Get Notified of The Best Changes in Technology, Plus Win Prizes in Our VIP Only Contests...

Tech News Tech Tutorials Smartphone News Tablet News Gaming News Free Software Infographics Contact