How to send email with php - tutorial & example

chris (2004-09-29 12:02:03)
13033 views
0 replies
So you want to know how to send emails with php. It's easy. This article identifies some of the methods available and then shows a simple way to send mime-encoded emails with just a few lines of code. My personal preference is to use the classes available on PEAR (which can be thought of as the php equivalent to CPAN). You can then use SMTP to relay your emails over somebody's mail server - either an open relay (if you can find one), or your own provider's mail server, (which is my personal preference).

First let's see what php.net has to say about it.. well the php docs for the mail() command state that 'mail() automatically mails the message specified in 'message' to the receiver specified in 'to'. Multiple recipients can be specified by putting a comma between each address in 'to'. Email with attachments and special types of content can be sent using this function. This is accomplished via MIME-encoding.

The problem

This is all very good, but if the system is to work, your webserver must have sendmail installed and must also be listening for connections and configured to enable relaying from your machine to the big wide world. There are many reasons why your webserver may not be set up in this way - many people will cite lists of security flaws with sendmail, and you will have to be very stringent in what characters you actually pass into the sendmail program. You would not want a user to enter shell meta characters into form inputs which are then handled by sendmail. The results could be disastrous.

The Solution

Further to this, if you are not the systems administrator of the webserver, it might be hard to persuade whoever is to install and configure sendmail, however installing a PEAR package is a very simple one-liner, so if the required packages aren't already on your system, I would strongly suggest this as an alternative route.


Making it work

So first the PEAR packages have to be installed. This is as simple as:

root@feodor# pear install Mail
root@feodor# pear install Mail_Mime

if you already have these packages installed, you can ensure that they are up to date with:

root@feodor# pear upgrade Mail
downloading Mail-1.1.4.tgz ...
Starting to download Mail-1.1.4.tgz (14,548 bytes)
.....done: 14,548 bytes
upgrade ok: Mail 1.1.4
root@feodor:# pear upgrade Mail_Mime
Package 'Mail_Mime-1.2.1' already installed, skipping

So you can see that the packages are now fully up to date on my system. Now all we need to do is include them into our php scripts and let them do the hard work.

There are different ways of using these mailer classes. You can opt to use a local sendmail binary for sending your emails with php just as the php mail() function does (discussed earlier), but if you want to you can use SMTP mail instead. This means that your php mailer will connect to somebody else's SMTP server. All you will need to do at the most is provide a username and a password. My ISP (Mailbox Internet) don't put any restriction on the number of messages I relay over their SMTP server - just so long as I'm connected to their network (i.e. I'm one of their customers), so here is some sample php code for sending these emails. The full version is at the end of this article for you to cut and paste.


So first I need to include the two php class files, Mail.php and Mail/mime.php which are going to do all the email work for me. These were installed by the PEAR installer and can be simply included like so:

	include_once('Mail.php');
	include_once('Mail/mime.php');

Now I need to specify some information about the email I wish to send. The usual fields are 'from', 'to' and 'subject'. In this example, I prepare some variables ($from, $recipients and $subject) which are then used as values in an array called $hdrs.

	$from="no-reply@mydomain.co.uk";
	$recipients="name1@domain.com, name2@domain2.com";
	$subject="Test Message";
	$text="this is a test message";
	$crlf = "n";
	$hdrs = array(
		'To'		=> $recipients,
		'From'		=> $from,
		'Subject'	 => $subject,
	);

My next job is to specify my mailserver and the authentication bits and pieces. All that's needed here is a hostname, a username and password. These are just the same as the username and password you use for your email account with your provider.

	$params["host"] = 'smtp.whatever.co.uk';
	$params["username"] = "myusername";        // authentication.
	$params["password"] = 'mypassword'; 

It's really very easy from here to send the email. I call the Mail_mime constructor to create a new mime object (called $mime). I can them call methods in this object to set the body text to be of type HTML. I also pass in my $hdrs array which provides the headers required for sending the email - ie the destination and return path etc (as specified above). Then the final job is to call the send method, passing in the list of destination email addresses, the headers array and of course the body text

	$mime = new Mail_mime($crlf);
	$mime->setHTMLBody($text);
	$body = $mime->get();
	$hdrs = $mime->headers($hdrs);
	$mail =& Mail::factory('smtp', $params);
	$mail->send($recipient, $hdrs, $body));

There really is no easier way to send email with PHP. I use this code with some database queries to get email addresses out of a mysql database and then to send the emails out. In fact, the full example below shows a function which I use to email all the administrators in one of the companies I work for. This provides an extra level of abstraction so that if a new administrator is added to the system, he/she will automatically receive any of the admin emails - with no change to code, or address lists.

So help yourself to the code, Please credit me or link back to spiration. If you have any comments, just sign up and hit reply. You can also use the subscribe tool in this channel to receive a notification whenever another article is posted on this subject. And see if you can guess what code handles those emails :). If you require full documentation of the Mail_mime PEAR package, it can be found here: PEAR Mail mime docs.

have fun,

Christo


--------------- sample function --------

function admin_email($text){
	global $db;

	$query="select us_email from users where us_level=10";
	$result=$db->query($query);
	if(DB::isError($result)){
		// handle the error
	}elseif($result->numRows()==0){
		// don't do anything
	}else{
		include_once('Mail.php');
		include_once('Mail/mime.php');
		$from="no-reply@mydomain.co.uk";
		$recipient=""; $i=0;
		while($row=$result->fetchRow()){
			if($i>0){$recipient.=", ";}
			$recipient.=$row['us_email'];
			$i++;
		}

		$crlf = "n";
		$hdrs = array(
			'To'      => $recipient,
			'From'    => $from,
			'Subject' => 'email from www.spiration.co.uk'
		);

		$params["host"] = 'your.smtp.host.com';
		$params["username"] = "username";        // authentication.
		$params["password"] = 'xxxxxxx';        // authentication.

		$mime = new Mail_mime($crlf);
		$mime->setHTMLBody($text);

		$body = $mime->get();
		$hdrs = $mime->headers($hdrs);
		$mail =& Mail::factory('smtp', $params);
		$mail->send($recipient, $hdrs, $body);                   
	}
}
comment