Section 20.3. Sending Mail


20.3. Sending Mail

The primary function for sending email is mail( ), which takes three basic parameters and one optional one. These parameters are, in order, the email address to send to, the subject of the message, the body of the message, and finally, any extra headers you want to include. Note that this function relies on a working email server that you have permission to use: for Unix machines, this is often Sendmail; Windows machines, you must set the SMTP value in your php.ini file.

Here is an example of the most basic type of mail( ) call:

     mail("a_friend@example.com", "My Subject", "Hello, world!"); 

If you receive mailing errors or don't receive the test mail, you have probably installed PHP incorrectly, or may not have permission to send emails.

You can use variables in place of any of the parameters, like this:

     $mailaddress = "a_friend@example.com";     $mailsubject = "My Subject";     $mailbody = "Hello, world!";     mail($mailaddress, $mailsubject, $mailbody); 

To make the email address textual, e.g., "A. Friend" rather than a_friend@example.com, you need to add both name and address values into the email address, like this:

     $mailtoname = "My Best Friend";     $mailtoaddress = "a_friend@example.com";     $mailtocomplete = "$mailtoname <$mailtoaddress>";     mail($mailtocomplete, "My Subject", "Hello, world!"); 

With that new code, the email will appear to have been sent to "My Best Friend", which is much easier to read. The fourth parameter is where you specify any number of additional email headers to send along with the emailthese let you affect how the email looks, how it is parsed, and other key information. For example, we can specify who sent the email using the From header, we can specify who else should get the email using the CC and BCC headers, or we can specify that the email is to be treated as containing HTML. Each header sent in the third parameter needs to be separated by a carriage return and new line, not just a new line. That is, only \r\n should be used to separate the various parameters, and not any other combination.

Here is a script that sends a HTML mail from a given email address:

     $message = "<b>This is a <i>test</i></b>";     $headers = "From: foo@bar.com\r\nContent-type: text/html\r\n";     mail("you@yourdomain.com", "Testing", $message, $headers); 

That should send a message with the text all in bold, and the word "test" in italics. The $headers variable is used to set From so that it appears to be from foo@bar.com, then add a carriage return and a new line, and finally send a Content-type header of text/html, which should make the email client display it as HTML. Because HTML emails allow potentially unsafe content, many email clients (such as KMail on Linux) will stop HTML emails being displayed by default, and will instead display a warningyou should be aware of this, and only use HTML email if it is necessary.

20.3.1. MIME Types

The Multipurpose Internet Mail Extensions (MIME) system was designed to allow the formatting of emails so that they can include files, and it is made up of several parts. In order to be able to instruct email clients what types of files are attached, MIME types were createdshort, textual descriptions of the file types that can be recognized by everyone. MIME types are so popular that they are used across the Web as a whole now, and many operating systems rely on them to decide how to open a file. In emails, attachments are literally copied into the message as an encoded string, with MIME boundary markers being used to tell mail readers where each attachment starts and stops.

There are MIME types for all sorts of formats, from application/zip for zip files to video/quicktime for Quicktime .mov files and application/x-tar for tarballs. It is the job of the Internet Assigned Numbers Authority (IANA) to assign official MIME types, and it also keeps a list of all the registered MIME types on its web site. At the time of writing, this list was available at http://www.iana.org/assignments/media-typesworth taking a look.

There are hundreds, possibly even thousands, of MIME types out there, simply because there are so many file formats out there. But there are a certain few that stand out as being popular, which are shown in Table 20-1.

Table 20-1. Mime types

application/msexcel

Microsoft Excel data file

application/msword

Microsoft Word data file

application/octet-stream

Generic binary file

application/pdf

Adobe PDF

application/x-shockwave-flash

Macromedia Flash

application/zip

Zip file

audio/mp3

MP3

audio/wav

Wave sound file

audio/x-ogg

Ogg file

font/ttf

TrueType Font

image/bmp

MS Windows .bmp image

image/gif

GIF image

image/jpeg

JPEG image

image/png

PNG image

image/tiff

TIFF image

image/svg+xml

Scalable Vector Graphic (SVG)

text/html

HTML file

text/plain

Plain text

text/rtf

Rich-Text File

text/tab-separated-values

Tab-Separated Values (TSV)

text/xml

XML

video/mpeg

MPEG video

video/quicktime

Quicktime video


MIME types are used in many places other than in emailsweb servers, for example, make very heavy use of MIME types in order to know how to handle files as they are requested, and also so they know what kinds of documents clients can and cannot receive.

It is undesirable to have to keep looking up long lists to find the MIME type you want every time you get a file, but PHP comes to the rescue with a special MIME lookup function, mime_content_type( ). This is based upon the Apache module mod_mime_magic, which itself is based upon the Unix file command. If you have never used this before, the principle is that many types of files have a unique identifier in the first few bytes, referred to as a magic number, that specifies what type of file it is. Bitmaps, for example, start with "BM", and MS DOS executables start with "MZ". By having a large lookup table of a selection of these magic numbers, it is quite easy to get an idea what kind of file is being examined, and thus what its MIME type should be.

To enable the MIME magic extension, you must either configure PHP with the switch ==with-mime-magic (Unix), or enable the extension in your php.ini file (Windows). On Windows, you will also need to edit one other entry in your php.ini filemime_magic.magicfile should be set to the directory where PHP was installed, with the subdirectory "extras". So if you installed PHP into c:\php, this would need to be set to c:/php/extras/magic.mime. On Unix, this extension relies on the file "magic," shipped with Apache. If PHP fails to find this for some reason, try setting the php.ini entry also.

Once you have the MIME magic extension working, you just need to pass a filename to mime_content_type( ) to get its MIME type as the return value, like this:

     print mime_content_type("myfiles.zip");     print mime_content_type("poppy.jpg"); 

Given that you actually have those files, that script should output application/zip and image/jpeg.

20.3.2. Easier Mail Sending with PEAR::Mail

Using PEAR::Mail ,we can write a simple email script like this:

     include('Mail.php');     $mail = Mail::factory("mail");     $headers = array("From"=>"me@example.com", "Subject"=>"Test Mail");     $body = "This is a test!";     $mail->send("best@friend.com", $headers, $body); 

The Mail.php file is the PEAR::Mail script, so it needs to be included before any PEAR::Mail functions are used. Line two creates a default instance of PEAR::Mailthe parameter mail is passed in so that PEAR::Mail will use PHP's mail( ) function to send the email. If you pass in sendmail, it will send direct via the sendmail program (Unix only).

Alternatively, you can pass in smtp, which lets you send a second parameter that is an array containing five keys: host, port, auth, username, and password. Each of these should have a value assigned to it: host should be the SMTP server to connect to, port should be the port number (defaults to 25), auth should be true if you want to authenticate with username and password (defaults to false), and username and password should be set if you want to authenticate. Unless you really want the extra power of connecting directly by hand, it's best to stick with mail( ).

Line three sets up the headers to use in the email. This time, we need to provide the subject inside a header, as well as the sender information. Here you can use all the techniques we have looked at so far; for example, the From element could have the value "Me <me@example.com>" to have the email addresses pretty-printed.

Line four sets the body text to use in the email, which is standard enough. Line five is where the email is actually sent, and you will see that send( ) takes three parameters: address to send to, headers to use, and the content of the email. The first parameter can either be a string with each person's name separated by a comma, or it can be an array.

20.3.3. Sending Mixed-Type Messages with PEAR::Mail_Mime

There is a close cousin of PEAR::Mail called PEAR::Mail_Mime that has a number of features to make sending attachments very easy.

The first type of attachment we are going to send does not even look like an attachment on the surface. Previous scripts sent HTML mail by adding "Content-type: text/html" to the headers. The problem with this is that people without a HTML mail reader cannot read the message, because they will receive a huge chunk of HTML and will have to dig through it by hand to find the message.

The solution here is to send the message in both plain text and HTML-encoded format, by attaching the HTML message separately. When the email is received by mail readers, they will automatically choose the correct one to display.

When Not To Use HTML Mail

Mailing lists, particularly those attached to the open source community, take a very strong stance against HTML emails. The reason for this is that your message gets sent twice inside the one emailonce in plain text and once in HTML. While this is fine for sending personal mails and mails to a controlled list who are willing to receive this, it does waste space in people's email inboxes and also wastes bandwidth for the list host.

We can do this using PEAR::Mail and PEAR::Mail_Mime, as the latter has a very simple way of attaching both a plain text mail and a HTML mail:


     include('Mail.php');     include('Mail/mime.php');     $message = new Mail_mime( );     $text = file_get_contents("mail_text.txt");     $html = file_get_contents("mail_html.html");     $message->setTXTBody($text);     $message->setHTMLBody($html);     $body = $message->get( );     $extraheaders = array("From"=>"me@example.com", "Subject"=>"My Subject 7");     $headers = $message->headers($extraheaders);     $mail = Mail::factory("mail");     $mail->send("best@friend.com", $headers, $body); 

Now the script includes both PEAR::Mail and PEAR::Mail_Mime, as it takes both classes to get the full email sent. Also, rather than handling our message as a text string, the message is an instance of Mail_mime. In the example, the message is stored in the $message variable. Next, both the plain text and HTML messages are retrieved from disk using file_get_contents( ) and stored in $text and $html, respectively.

Once we have the content loaded, we can put it into the message using the setTxtBody( ) and setHTMLBody( ) methods of our $message variable. These both take a string as their only parameter, so just pass in the appropriate return value from file_get_contents( ).

The body for the message, still stored in $body, now comes from the return value of $message->get( ). This retrieves the full message text to send, and is a combination of the HTML and text information all encoded for sending over the Internet. If you want to see how the system works behind the scenes, echo out $body and have a look through.

With the line starting "$extraheaders = ", things begin to get more complicated. The PEAR::Mail->send( ) function takes its headers as an array and, to accommodate this, PEAR::Mail_Mime also returns its headers as an array. When sending complex emails, you need to have a special set of headers in there that tells the mail reader what to expect. So, once you have your content in place, you just call headers( ) to get the header information. As you still need to use the old headers (from, subject, etc.), you can pass into headers( ) an array of existing headers, and it will add these to the array it returns.

For example, calling headers( ) on its own might return something like this:

     array(2) {             ["MIME-Version"]=>             string(3) "1.0"             ["Content-Type"]=>             string(64) "multipart/mixed;             boundary="=_067d506611ba7a0da2b6106b54282d16""     } 

However, passing our array $extraheaders in as the only parameter, headers( ) returns this:

     array(4) {             ["MIME-Version"]=>             string(3) "1.0"             ["From"]=>             string(14) "me@example.com"             ["Subject"]=>             string(12) "My Subject 7"             ["Content-Type"]=>             string(64) "multipart/mixed;             boundary="=_307c199ae5303dac356d5cf48c89fc7c""     } 

The "boundary" string in Content-Type is randomized, so yours will be different.

Once we have the complete list of headers, this is passed into the send( ) call at the end, which is otherwise unchanged. Now when the mail is received, mail readers should automatically pick the best format for them and display it.

20.3.4. Sending Real Attachments

Using PEAR::Mail_Mime makes it very easy to add attachments to your messages. Add this line after the call to setHTMLBody( ):

     $message->addAttachment("example.txt"); 

You will, of course, need to change example.txt to the name of a file in the same directory as the script. That's all it takes to add an attachment once you are using PEAR::Mail and PEAR::Mail_Mime.

If you run the script again, you should see the attachment has come through properly. However, there is one more thing you can do with PEAR::Mail_Mime and attachments, and that is to attach HTML images. These are essentially the same thing as attachments, except they are not shown as an attachment in most HTML-compliant mail readers; they are shown only in the message body. This makes better sense for HTML pictures, because it would likely confuse people to see a dozen pictures attached to the mail that aren't of importance.

To add a HTML picture, use the addHTMLImage( ) function. As with addAttachment( ), this takes the filename to attach as its only parameter. In order to use this picture, you need to edit the HTML file you are attaching and add the appropriate line, for example:

     // in the PHP file:     $message->addHTMLImage("button.png");     // and in the HTML file:     <IMG src="/books/1/302/1/html/2/button.png" /> 

Now when you send the mail, button.png should be sent along and displayed inside the message. In Outlook, this results in the first picture file being attached, and the second file being attached (but not listed as an attachment) and shown inside the messageperfect!



PHP in a Nutshell
Ubuntu Unleashed
ISBN: 596100671
EAN: 2147483647
Year: 2003
Pages: 249

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net