Sending mail to external addresses

Một phần của tài liệu Professional PHP Programming phần 8 pptx (Trang 45 - 61)

The standard IMAP protocol we choose is well supported by PHP, and when the two are combined produce a very suitable programming environment for making this application. Powerful and versatile results can be accomplished quickly, by the combination of multiple PHP IMAP functions.

The PHP function, imap_open(), performs the first step by logging into the mail server. A sample statement is given below:

int imap open(string mailbox, string username, string password, int [flags]);

where the mailbox string needs to be in the form of:

"{" remote system name [":" port] [flags] "}"[mailbox name]

For example, "{mail.domain.com:###}INBOX" is a valid remote IMAP mailbox specification. The results of imap_open() produce an IMAP stream, which can be used by the other IMAP PHP functions to retrieve various information. The IMAP stream is an important feature because it allows multiple IMAP connections to even different IMAP servers within the same script.

Once the IMAP connection is established, we can use a function called imap_headers to return a list of all the mail messages in our mailbox. The resulting list of mail messages can be output to the screen, taking care of the first step in mail access, listing a mailbox’s contents. The function imap_headers() can be used in the form below:

array imap_headers(int imap_stream);

The result that imap_headers returns, is an array of strings formatted with header info, one element per mail

message. The format it returns becomes very important in that we are able to not only displaying a list of messages but also to provide a link to the actual mail message. To do this, we take the resultant array, loop through each array element printing out the header information. While this occurs each message header is assigned a URL link to view the contents of the actual message before the cycle continues. A sample set of code that shows the individual steps is below where the URL in the example is view.php:

<?php

// list.php

$username = "musone";

$password = "secret";

$mailserver = "{localhost/imap}";

$link = imap open($mailserver, $username, $password);

$headers = imap headers($link);

for ($x=1; $x <= count($headers); $x++) { $idx = $x-1;

echo "<A HREF=\"view.php?num=$x\">$headers[$idx]</A><BR>";

}

?>

Once we produce the list of available mail messages, we will need to provide a method so each mail message can be accessed. The approach we have shown previously takes advantage of many of the benefits of PHP while using a standard mail protocol. We save a great amount of time being able to query a mailbox right from within a dynamic html page without having to spawn any additional processes or reference any other files. You can also plainly see that returning just the mail headers with the result not only delivers all the pertinent information we need for display, but also reduces the overall return time over trying to fetch the entire messages.

Moving to the next step, viewing a particular mail message, we again will need to first open an IMAP connection with imap_open(). We then use the first of two other PHP functions, imap_header(), which first takes in a message number and returns an associative array with each of the mail headers as elements. The syntax for imap_header(),

string imap_header(int imap_stream, int msgno, int flags);

This function causes a fetch of the complete header of the specified message as a text string and returns that text string.

Displaying the body of the message is the second step for viewing single messages. Another PHP function,

imap_body(), similar to imap_fetchheader() except that it returns the message body, is the essential part of this step. Sample imap_body() syntax is printed below:

string imap body(int imap stream, int msg number);

For a given msg_number in the current mailbox, imap_body() returns the corresponding message body. Since the return contents for both functions are only the text message, we can simply echo the contents right to the web browser. The entire view.php file, presented below, does nothing more than create a simple IMAP connection, fetch the header information, and fetch the body text for a particular message.

<?php

// view.php

$username = "musone";

$password = "secret";

$mailserver = "{localhost/imap}";

$link = imap open($mailserver, $username, $password);

echo("<PRE>");

echo(imap fetchheader($link,$num));

echo("<BR><P>");

echo(imap body($link,$num));

echo("</PRE>");

?>

A sample output below shows the header information followed by the message body:

Any serious mail application will also need the ability to manipulate mail messages. Therefore, we need to add ways to delete and reply to this single mail message.

To accomplish this let’s add two links to the bottom of the message reading page by altering the file view.php.

The first link will be to delete the message and then the second link will be to reply to it.

<?php

// view.php

$username = "musone";

$password = "secret";

$mailserver = "{localhost/imap}";

$link = imap open($mailserver, $username, $password);

echo("<PRE>");

echo(imap fetchheader($link,$num));

echo("<BR><P>");

echo(imap body($link,$num));

echo("</PRE>");

?>

<FORM ACTION="delete.php">

<INPUT TYPE="hidden" NAME="num" VALUE="<?php echo($num); ?>">

<INPUT TYPE="submit" NAME="Delete" VALUE="Delete">

</FORM>

<FORM ACTION="reply.php">

<INPUT TYPE=HIDDEN NAME="num" VALUE="<?php echo($num); ?>">

<INPUT TYPE=SUBMIT NAME="Reply" VALUE="Reply">

</FORM>

Now we offer the user two specific options when they have finished viewing the message, they can either delete the message or reply to the sender. Let's look into the delete.php file.

This file should be fairly simple. From the submitted form, it takes in a variable $num which contains the message number. All we need from delete.php is to open up the mailbox, delete the mail message, and expunge the mailbox.

Note that in the IMAP world, issuing an imap_delete() command simply flags a specific message for deletion, while imap_expunge() does the actual removal of mail messages marked for deletion. This setup, though it may look otherwise, can actually lower the server load. For instance, multiple messages can be flagged for deletion before imap_expunge() is run; say when the flag count reaches a certain level or the user leaves the site. So, even though imap_delete() will not decrease, the imap_expunge() can be reduced in most cases to once.

Although multiple options are available, here is a sample of the delete.php file:

<?php

// delete.php

$username = "musone";

$password = "secret";

$mailserver = "{localhost/imap}";

$link = imap open($mailserver, $username, $password);

imap delete($link, $num);

imap expunge($link);

?>

Message Deleted!

Before we go on to replying to a mail message, lets first put in the ability to simply send a mail message. The reason behind this is that replying to a mail message is almost the same as sending a mail message. The biggest difference lies in that replying to a mail message removes the requirement to specify the email address of the recipient (since it can be retrieved from the original message).

The mail() function, native to PHP, is all we need to use to accomplish this step. The function is quick and simple to follow. The message composition will need a web page form that will accept a remote email address, a subject for the mail message, and a place to type in body content, like this below:

<HTML>

<!-- Compose.php -->

<FORM ACTION="sendmail.php" METHOD=POST>

To:<INPUT TYPE="text" NAME="to"><BR>

Subject:<INPUT TYPE=TEXT NAME="subject"><BR><BR>

<CENTER>Enter Mail Message Here</CENTER><BR>

<TEXTAREA NAME="body" ROWS=10 COLS=50></TEXTAREA><BR>

<INPUT TYPE=SUBMIT VALUE="Send Message">

</FORM>

</HTML>

The web result of this form would look something like this:

This form would send the information, when the "SUBMIT" button is pressed, to a PHP script page that would perform the mail function and if possible, echo out any success/error web messages. A simple script for sending mail is shown below:

<?php

// sendmail.php

if (mail($to, $subject, $body)) { echo("Message sent!");

} else {

echo("Unable to send message!");

}

?>

To reply to a mail message is a little more complicated. The reason for its complexity is that in order to reply to a mail message, you need to know who the original sender of the mail message was.

We can get this information out of the mail message by calling the imap_header() function. The

imap_header() function, unlike the imap_fetchheader() function returns an object with the entire header elements broken down. We will be looking at where the mail message came from, the From: line in the mail message.

To find the email address of the sender, the parts of the object returned from the imap_header() function is the from[] array.

Let us assume that the returned object is called $header_object, we'll want the first from address, which can be retrieved by:

$sender=$header_object->from[0];

This sender object is itself an object that contains the username and host of the sender.

To send the reply message we need to retrieve the individual parts from the original message by:

$sender_username=$sender->mailbox;

$sender host=$sender->host;

Putting this all together in reply.php results in:

<HTML>

<FORM ACTION="sendmail.php" METHOD=POST>

Subject:<INPUT TYPE=TEXT NAME="subject"><BR>

<CENTER>Enter Mail Message Here</CENTER><BR>

<TEXTAREA NAME="body" ROWS=10 COLS=50></TEXTAREA><BR>

<?php

$username = "musone";

$password = "secret";

$mailserver = "{localhost/imap}";

$link = imap open($mailserver, $username, $password);

$header object = imap header($link, $num);

$sender = $header object->from[0];

$sender username = $sender->mailbox;

$sender host = $sender->host;

?>

<INPUT TYPE=HIDDEN NAME="to" VALUE="<?php echo("$sender username@$sender host") ?>">

<INPUT TYPE=SUBMIT>

</FORM>

</HTML>

Note that the form submits to the same place as the script that composes a new mail message. The only real difference is that the reply is a "more intelligent" compose screen, in that the To: line has already been formatted.

We can now put this all together, wrapped by a friendlier user interface. We also want to change the pages to use a username and password that is supplied by the user. For this, we will use PHP's authentication scheme.

Unfortunately, this has been found only to work if PHP is running as an Apache module, it will not work on IIS or in the Apache/CGI version. The code that is given below will give you basic security regulation for access to the application, the script will attempt to identify your username and password against those of authenticated users, for more information on security see Chapter 20 (Security).

index.php

<?php

if(!isset($PHP_AUTH_USER)) {

Header("WWW-Authenticate: Basic realm=\"XYZ Web Mail\"");

Header("HTTP/1.0 401 Unauthorized");

echo "Text to send if user hits Cancel button\n";

exit;

} else {

echo "Hello $PHP_AUTH_USER.<P>";

echo '<a href="list.php">Read Mail</a><P>’;

echo '<a href="write.php">Write Mail</a><P>’;

}

?>

This page will either prompt for a username and password for the mail account, or if one is given, will show the main menu. The main menu consists of reading mail or writing mail.

list.php

<?php

$MAILSERVER= "{localhost/imap}";

$link=imap_open($MAILSERVER,$PHP_AUTH_USER,$PHP_AUTH_PW);

$headers=imap_headers($link);

for($x=1; $x < count($headers); $x++) {

$idx=($x-1);

echo "<a href=\"view.php?num=$x\">$headers[$idx]</a><br>";

}

?>

Note that the main difference between this and the original script that listed the messages is that the username and password are no longer hardcoded. The username and password are now the ones specified in the PHP_AUTH_USER and PHP_AUTH_PW variables. Our original files will change accordingly to incorporate the authentication process.

Below are all the final code examples from the chapter.

view.php

<?php

$MAILSERVER= "{localhost/imap}";

$link=imap_open($MAILSERVER,$PHP_AUTH_USER,$PHP_AUTH_PW);

echo $imap_fetchheader($link,$num);

echo "<BR>";

echo imap_body($link,$num);

?>

<FORM ACTION="delete.php">

<INPUT TYPE="hidden" NAME="num" VALUE="<?php echo $num ?>">

<INPUT TYPE="submit" NAME="Delete" VALUE="Delete">

</FORM>

<FORM ACTION="reply.php">

<iNPUT TYPE="hidden" NAME="num" VALUE="<?php echo $num ?>">

<INPUT TYPE="submit" NAME="Delete" VALUE="Delete">

</FORM>

delete.php

<?php

$MAILSERVER= "{localhost/imap}";

$link=imap_open($MAILSERVER,$PHP_AUTH_USER,$PHP_AUTH_PW);

imap_delete($link,$num);

imap_expunge($link);

?>

Message Deleted!

<A HREF="login.php">Back to menu</A>

compose.php

<FORM ACTION="sendmail.php" METHOD="POST">

To:<INPUT TYPE="text" NAME="to"><br>

Subject:<INPUT TYPE="text" NAME="subject"><BR>

<CENTER>Enter Mail Message Here</CENTER><BR>

<TEXTAREA NAME="body" rows=10 cols=50></TEXTAREA><BR>

<INPUT TYPE="submit">

</FORM>

reply.php

<FORM ACTION="sendmail.php" METHOD="POST">

Subject:<INPUT TYPE="text" NAME="subject"><BR>

<CENTER>Enter Mail Message Here</CENTER><BR>

<TEXTAREA NAME="body" ROWS=10 COLS=50></TEXTAREA><BR>

<?php

$MAILSERVER= "{localhost/imap}";

$link=imap_open($MAILSERVER,$PHP_AUTH_USER,$PHP_AUTH_PW);

$header_object=imap_header($link,$num);

$sender=$header_object->from[0];

$sender_username=$sender->mailbox;

$sender_host=$sender->host;

?>

<INPUT TYPE="hidden" NAME="to" VALUE="<?phpecho "$sender_username@$sender_host"?>">

<INPUT TYPE="submit">

</FORM>

sendmail.php

<?php

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

?>

Message Sent!

<A HREF="login.php">Back to menu</A>

The above scripts are all that is necessary for a simple, yet versatile web mail system.

Summary

From here, one can expand this system to almost limitless capacities. The first step is to probably make the mail interface look prettier. This would consist of doing things like adding tables and backgrounds and colors to various text elements. The next step would possibly to add frames to separate the navigation from the system output.

Other additions to this are adding the original message body to a reply, and creating an address book system.

Although the address book itself would not have much to do with IMAP, a PHP interface that ties some backend address book such as LDAP and the mail composition screen would be quite nice.

26

Case Study 4: Databases

There are many web sites which user a database server as the backend, and of those a growing number use PHP to accomplish this connectivity and produce dynamic content. In this chapter, we will look at the code behind one such site, the Metalloprotein-site Database and Browser (MDB).

The MDB site is the interface to a database of structural information on metal-binding sites in

macromolecules from the Protein Data Bank (PDB, http://www.rcsb.org/). If this is meaningless to you and you know nothing about metalloproteins, we'll have a quick look at them. But don't worry, you can easily skip over the next paragraph and you won't lose much of the gist of the discussion in the coming sections, because the discussion here concentrates not on the database itself, but on the way we can use the database to create documents dynamically.

So, what is a protein? You may have heard of amino acids; think of amino acids as building blocks, and proteins as the structures built from these blocks. The amino acids join to each other to form a chain, which can collapse to form a compact three-dimensional object, in a similar way to a piece of thread wound in on itself to form a ball of twine. This three-dimensional object has a texture, a topology, with hills and valleys, with meadows and deep crevices (see figure below of the surface of the protein Hemoglobin). Proteins can bind metal ions to these concavities or convexities. Such proteins are called metalloproteins, and form about one third of all known proteins. Metalloproteins are vital to life, and without them it would be impossible to metabolize nutrients and even to get oxygen to all the cells in the body. Hence the effort to understand their three-dimensional structure and properties.

This image shows two representations of the same metalloprotein; the one on the left shows the backbone structure with the metal ions (iron) represented as spheres. On the right, is the same protein (in the same orientation), shown as a three-dimensional object with the electrostatic potential mapped to its surface.

Notice all the knobs, clefts, and other topological features on this protein surface.

Một phần của tài liệu Professional PHP Programming phần 8 pptx (Trang 45 - 61)

Tải bản đầy đủ (PDF)

(86 trang)