Send a Private Message on Your Website
- Private Messaging on Your Website
- Private Message Login
- Private Message Logout
- Private Message Sending Form
- Send Private Message
- Private Message Inbox — Received Messages
- Private Message Outbox — Sent Messages
- Check Private Message Session ID
- Delete Received Private Message
- Delete Sent Private Message

This page is a tutorial on a script for sending a private message (PM) on your website. It uses sessions, MySQL, PHP, input filtering, JavaScript, HTML, and a menu system. The menu on the side bar lets you send a message or check out your inbox or outbox, or delete messages from your inbox or outbox or logout. The screenshot above is the private message inbox.
Let's check out the code. It starts with a PHP include that insists on adding the php file checkid.php to this page's content. All that's in this file is:
session_start();
if(!isset($_SESSION['sessionid'])){
session_unset();
session_destroy();
header('location: message-login.php');
}else{
// session logged
}
This just does what it ought to: start a session (it started in the login page, actually, but we can say we restarted it even though we merely continued it and restarted the session timeout clock which is set for 24 to 48 minutes, depending on the PHP installation directives). We then check the session variable "sessionid" which was saved at login. If it's not set, the user is sent to the login page after unsetting and destroying the session. If it is set, the user gets to continue the script since the else conditional leads only to a comment that does nothing, but says it all: "session logged." So the user is okay and good to go.
Next we get ready to access the MySQL database by using the include with config.php in it. Then we create the table privatemessages if it doesn't already exist. This is for storing message data. Then we get three POSTed values, sent from the Private Message Sending Form page. These are touser, subject, and message, which we use the php function strip_tags() on just in case. We check to see if they are empty or insincere (only 1 or 2 characters long). If they are, the user gets this message: "Fill form completely, please."
Then we make sure none of these variables contain anything but letters, numbers, comma, period, question mark, exclamation mark, or space, using the
preg_replace() function. We replace any unacceptable characters with an empty string—in essense deleting them. Just for good measure, we run the database security function mysql_real_escape_string() on these strings because they'll be going into a MySQL database table. This escapes the following characters: \x00, \n, \r, \, ', ", \x1a, but we've already taken care of them in the preg_replace() function, so we do it only because its a good habit to get into for security reasons. Since there couldn't be any unacceptable characters in them, we felt free to save them as session variables—so we did. (Note: feel free to define "unacceptable characters" in your own way, altering the regular expression pattern as you see fit.)
Now we insert the various message related data into the MySQL database table privatemessages. More about this in the The NULL vs. '' Controversy section, below.
Using SELECT, we now find the email address of the person who is "touser" and use it to send him or her an email saying "You have a new private message on our Website!" You'll want to change "your-site.com" to the real thing. Finally, we close MySQL and give the message "Message sent."
The NULL vs. '' Controversy
When we insert the various message related data into the MySQL database table, privatemessages, note that NULL is used to prompt the id field to auto-increment. When no value is specified for an AUTO_INCREMENT column, MySQL assigns sequential numbers automatically. You can simply ignore that field and it will take care of incrementing itself, but you can also explicitly assign NULL or 0 to the column to generate sequential numbers. All 3 methods work.
There's a bit of a controversy online over whether '' (2 single quotes) will also work. Some say yes and some say no. We've used this method on dozens of scripts, as have hundreds of PHP/MySQL example sites on the Net. We were using PHP 5.2 and MySQL 4 in the past but have just updated to MySQL 5. The '' method still works fine for prompting an auto-increment field, even though some predicted it would not work in MySQL 5.
Apparently some people got all bent out of shape because the MySQL manuals do not SAY that '' will work. They also don't say it won't. If you were a MySQL parser and had to evaluate a couple of single quotes as an inserted auto-incrementing, primary field value, what would you do? Leave the field empty? This would lead to much grief. Throw an error? Again—much grief. Since there are thousands of online examples using this method and thousands of PHP files on thousands of servers using it, what possible reason would Oracle have for making this code throw an error when they updated their MySQL engine from 4 to 5? They would have thousands if not millions of unhappy users, failing scripts, incorrect examples online that do not specify version, a flood of angry calls, letters, emails, and forum rants.
Programmers really, really, really do NOT want to comb through all their files on servers and redo them senselessly. The assumption by some that '' means an empty string which is incompatible with an auto-incrementing integer field is silly. Think about it. When you insert values, you put single quotes around them. See for yourself whether numbers also get these single quotes during INSERT INTO commands. If these guys don't know how to do it, who does? Our point here is that single quotes indicate VALUES. They do not specifically indicate strings and therefore incompatibility with integer auto-increment fields.
The Mysql 4 vs Mysql 5 auto-increment field on insert controversy should be laid to rest here where someone who "knew for a fact" it would throw an error in MySQL 5 was enlightened by someone who tested that theory right then and there in his MySQL on his server and found that even 2 single quotes with a SPACE between them got the id field to auto-increment. However, when his db was asked pointedly about it with a mysql> show warnings command, there was an "Out of range value adjusted for column 'id' at row 1" error even though the code worked fine. Is this a special version of MySQL?
We've never gotten any complaints from our MySQL 4 or 5. However, we'll start using NULL instead of '' just because the manual advises this, but NOT because it won't work right with '', which both the page link above and our own experience has disproven. We advise others: use NULL, please, since someday someone in the MySQL part of Oracle may just decide to lay errors on those who don't, thereby causing an enormous amount of grief as scripts all over the place fail and throw errors. Why would they be so naive, egotistical, and inconsiderate? They wouldn't, unless some stupid person gets in a position of power there, which is extremely unlikely. What we've seen from Oracle and MySQL is wise, nicely debugged, clean database engines they can be proud of. We expect this to continue. But, just in case . . . . . use NULL!
Name the file send-message.php
<?php
include_once"checkid.php";
//send-message.php
include('config.php');
$sql = "CREATE TABLE IF NOT EXISTS privatemessages (
id INT(4) NOT NULL AUTO_INCREMENT,
touser VARCHAR(40) NOT NULL,
fromuser VARCHAR(40) NOT NULL,
subject VARCHAR(150) NOT NULL,
message TEXT NOT NULL,
readit ENUM('0','1') NOT NULL DEFAULT '0',
deleted ENUM('0','1') NOT NULL DEFAULT '0',
datesent VARCHAR(40) NOT NULL,
outdel ENUM('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (id)
) ENGINE=MyISAM AUTO_INCREMENT=1";
mysql_query($sql);
$touser = strip_tags($_POST['touser']);
$subject = strip_tags($_POST['subject']);
$message = strip_tags($_POST['message']);
if(!isset($touser) || !isset($subject) || !isset($message) || strlen($touser)<3 || strlen($subject)<3 || strlen($message)<3){
echo '<script language="javascript">alert("Fill form completely, please."); window.location = "send-message-form.php"; </script>';
}else{
$pattern2 = '/[^a-zA-Z0-9\\s\\.\\,\\!\\?]/i';
$replacement = '';
$touser=preg_replace($pattern2, $replacement, $touser);
$touser=mysql_real_escape_string($touser);
$subject=preg_replace($pattern2, $replacement, $subject);
$subject=mysql_real_escape_string($subject);
$message=preg_replace($pattern2, $replacement, $message);
$message=mysql_real_escape_string($message);
$fromuser = $_SESSION['username'];
$_SESSION['subject'] = $subject;
$_SESSION['message'] = $message;
$_SESSION['touser'] = $touser;
$time = time();
$sql = mysql_query("INSERT INTO privatemessages
(id,touser,fromuser,subject,message,readit,deleted,datesent,outdel)
VALUES (NULL, '$touser', '$fromuser', '$subject', '$message', '0', '0', '$time', '0')");
$sql = mysql_query("SELECT email FROM messagemembers WHERE username = '$touser'");
$row=mysql_fetch_assoc($sql);
$e=$row['email'];
$to = $e;
$subject = "You have a new private message on our Website!";
$message = "You have a new private message on our Website, ".$touser.".\n\nClick link to log in and see it: http://www.your-site.com/message-login.php \n\nDo not reply to this email.\n\nRegards,\n\nour Website's management";
$headers = "From: NO-REPLY@your-site.com";
$mail_sent = mail($to, $subject, $message, $headers);
mysql_close();
echo '<script language="javascript">alert("Message sent."); window.location = "send-message-form.php"; </script>';
}
?>