Mail Management Application
Mail Management Application
http://www.informit.com/articles/printerfriendly.aspx?p=1924985
Note the use of UNIQUE in the eld de ni on for email. This means that although id is the primary key, duplicates should not be allowed in the email eld either. The email eld is a unique key, and id is the primary key. Log in to MySQL via the command line and issue this query. A er crea ng the table, issue a DESC or DESCRIBE query to verify that the
1 trong 10
25/09/2013 2:06 PM
Articles
http://www.informit.com/articles/printerfriendly.aspx?p=1924985
table has been created to your speci ca ons, such as the following:
mysql> DESC subscribers; +-------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra |
| email | varchar(150) | NO
Now that you have a table in your database, you can create the form and script that place values in there.
Lines 315 set up the rst func on, doDB(), which is simply the database connec on func on. If the connec on cannot be made, the script exits when this func on is called; otherwise, it makes the value of $mysqli available to other parts of your script. Lines 1726 de ne a func on called emailChecker(), which takes an input and returns an outputlike most func ons do. We look at this one in the context of the script, as we get to it in Lis ng 19.2 Save this le as ch19_include.php and place it on your web server. In Lis ng 19.2, you will see how to include this le when necessary in your scripts.
2 trong 10
25/09/2013 2:06 PM
Articles
http://www.informit.com/articles/printerfriendly.aspx?p=1924985
The subscrip on form is actually an all-in-one form and script called manage.php, which handles both subscribe and unsubscribe requests. Lis ng 19.2 shows the code for manage.php, which uses a few user-de ned func ons to eliminate repe ous code and to start you thinking about crea ng func ons on your own. The code looks long, but a line-by-line descrip on follows (and a lot of the code just displays an HTML form, so no worries).
3 trong 10
25/09/2013 2:06 PM
Articles
http://www.informit.com/articles/printerfriendly.aspx?p=1924985
69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103:
//get number of results and do action if (mysqli_num_rows($check_res) < 1) { //free result mysqli_free_result($check_res); //print failure message $display_block = "<p>Couldn't find your address!</p> <p>No action was taken.</p>"; } else { //get value of ID from result while ($row = mysqli_fetch_array($check_res)) { $id = $row['id']; } //unsubscribe the address $del_sql = "DELETE FROM subscribers WHERE id = ".$id; $del_res = mysqli_query($mysqli, $del_sql) or die(mysqli_error($mysqli)); $display_block = "<p>You're unsubscribed!</p>"; } mysqli_close($mysqli); } } ?> <!DOCTYPE html> <html> <head> <title>Subscribe/Unsubscribe to a Mailing List</title> </head> <body> <h1>Subscribe/Unsubscribe to a Mailing List</h1> <?php echo "$display_block"; ?> </body> </html>
ch19_include.php
Lis ng 19.2 might be long, but its not complicated. In fact, it could be longer were it not for the user-de ned func ons placed in and included on line 2 of this script.
Line 4 starts the main logic of the script. Because this script performs several ac ons, you need to determine which ac on it is currently a emp ng. If the presence of $_POST is false, you know that the user has not submi ed the form; therefore, you must show the form to the user. Lines 625 create the subscribe/unsubscribe form by storing a string in the $display_block variable using the heredoc format. In the heredoc format, the string delimiter can be any string iden er following <<<, as long as the ending iden er is on its own line, as you can see in this example on line 25. NOTE You can learn more about the heredoc and other string formats in the PHP Manual at h p://www.php.net/manual /en/language.types.string.php. In the form, we use $_SERVER[PHP_SELF] as the ac on (line 7), and then create a text eld called email for the users email address (lines 911) and set up a set of radio bu ons (lines 1321) to nd the desired task. At the end of the string crea on, the script breaks out of the if...else construct, skips down to line 101, and proceeds to print the HTML stored in the $display_block variable. The form displays as shown in Figure 19.1.
4 trong 10
25/09/2013 2:06 PM
Articles
http://www.informit.com/articles/printerfriendly.aspx?p=1924985
Figure 19.1 The subscribe/unsubscribe form. Back inside the if...else construct, if the presence of $_POST is true, you need to do something. There are two possibili es: the subscribing and unsubscribing ac ons for the email address provided in the form. You determine which ac on to take by looking at the value of $_POST['action'] from the radio bu on group. In line 26, if the presence of $_POST is true and the value of $_POST['action'] is "sub", you know the user is trying to subscribe. To subscribe, the user needs an email address, so check for one in lines 2830. If no address is present, redirect the user back to the form. However, if an address is present, call the doDB() func on (stored in ch19_include.php) in line 34 to connect to the database so that you can issue queries. In line 36, you call the second of our user-de ned func ons: emailChecker(). This func on takes an input ($_POST['email'], in this case) and processes it. If you look back to lines 2125 of Lis ng 19.1, youll see code within the emailChecker() func on that issues a query in an a empt to nd an id value in the subscribers table for the record containing the email address passed to the func on. The func on then returns the resultset, called $check_res, for use within the larger script. NOTE Note the de ni on of global variables at the beginning of both user-de ned func ons in Lis ng 19.1. These variables need to be shared with the en re script, and so are declared global. Jump down to line 39 of Lis ng 19.2 to see how the $check_res variable is used: The number of records referred to by the $check_res variable is counted to determine whether the email address already exists in the table. If the number of rows is less than 1, the address is not in the list, and it can be added. The record is added, the response is stored in lines 4448, and the failure message (if the address is already in the table) is stored in line 54. At that point, the script breaks out of the if...else construct, skips down to line 101, and proceeds to print the HTML currently stored in $display_block. Youll test this func onality later. The last combina on of inputs occurs if the presence of $_POST is true and the value of the $_POST['action'] variable is "unsub". In this case, the user is trying to unsubscribe. To unsubscribe, an exis ng email address is required, so check for one in lines 5961. If no address is present, send the user back to the form. If an address is present, call the doDB() func on in line 64 to connect to the database. Then, in line 67, you call emailChecker(), which again returns the resultset, $check_res. Line 70 counts the number of records in the result set to determine whether the email address already exists in the table. If the number of rows is less than 1, the address is not in the list and it cannot be unsubscribed. In this case, the response message is stored in lines 7576. However, if the number of rows is not less than 1, the user is unsubscribed (the record deleted) and the response is stored in lines 8488. At that point, the script breaks out of the if...else construct, skips down to line 101, and proceeds to print the HTML. Figures 19.2 through 19.5 show the various results of the script, depending on the ac ons selected and the status of email addresses in the database.
5 trong 10
25/09/2013 2:06 PM
Articles
http://www.informit.com/articles/printerfriendly.aspx?p=1924985
6 trong 10
25/09/2013 2:06 PM
Articles
http://www.informit.com/articles/printerfriendly.aspx?p=1924985
Figure 19.5 Unsuccessful unsubscribe ac on. Next, you create the form and script that sends along mail to each of your subscribers.
7 trong 10
25/09/2013 2:06 PM
Articles
http://www.informit.com/articles/printerfriendly.aspx?p=1924985
37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61:
$mailheaders = "From: Your Mailing List <you@yourdomain.com>"; //loop through results and send mail while ($row = mysqli_fetch_array($result)) { set_time_limit(0); $email = $row['email']; mail("$email", stripslashes($_POST['subject']), stripslashes($_POST['message']), $mailheaders); $display_block .= "newsletter sent to: ".$email."<br/>"; } mysqli_free_result($result); mysqli_close($mysqli); } } ?> <!DOCTYPE html> <html> <head> <title>Sending a Newsletter</title> </head> <body> <h1>Send a Newsletter</h1> <?php echo $display_block; ?> </body> </html>
As in Lis ng 19.2, the le of user-de ned func ons is included on line 2. Although only the database connec on func on is used in this le, theres no harm in having the other func on in the le, as well. The main logic of the script starts at line 3, where you determine whether the user has seen the form yet. If the presence of the $_POST variable is false, you know the user has not submi ed the form; therefore, you must show the form. Lines 515 create the form for sending the newsle er to your subscriber list, which uses $_SERVER[PHP_SELF] as the ac on (line 6), creates a text eld called subject for the subject of the mail, and creates a textarea called message for the body of the mail to be sent. At this point, the script breaks out of the if...else construct, and the HTML is printed. The form displays as shown in Figure 19.6.
Figure 19.6 Form for sending the bulk mail. If the presence of $_POST is not false, the script should send the form to the email addresses in the subscribers table. Before sending the message, you must check for the two required items from the form in lines 1820: $_POST['subject'] and $_POST['message']. If either of these items is not present, redirect the user to the form again. If the required items are present, the script moves on to line 24, which calls the database connec on func on. A query is issued in line 33, which grabs all the email addresses from the subscribers table. There is no order to these results, although you could throw an order by clause in there if you want to send them out in alphabe c order for whatever reason.
8 trong 10
25/09/2013 2:06 PM
Articles
http://www.informit.com/articles/printerfriendly.aspx?p=1924985
Lines 3738 create a From: mail header, which is used inside the upcoming while loop, when the mail is sent. This header ensures that the mail looks like it is from a person and not a machine because youve speci cally provided a value in this string. The while loop, which begins on line 40, extracts the email addresses from the resultset one at a me. On line 41, you use the set_time_limit() func on to set the me limit to 0, or no limit. Doing so allows the script to run for as long as it needs to. CAUTION Because the script in Lis ng 19.3 simply executes the mail() func on numerous mes, it does not take into account the queuing factors in actual mailing list so ware, which are designed to ease the burden on your outgoing mail server. Using set_time_limit() does not ease its burden; it just allows the script to con nue to run when it might have med out before. In lines 4344, the mail is sent using the mail() func on, inser ng the values from the form where appropriate. Line 45 adds to a string that is later printed to the screen, which shows to whom the mail was sent. Figures 19.7 and 19.8 show the outcome of the script.
Summary
In this chapter, you applied your basic PHP and MySQL knowledge to the crea on of a personal mailing list. Included were the database table crea on, the subscribe and unsubscribe mechanisms, and the form and script for sending the mail.
Q&A
Q. How can I ease the burden on my mail server? A. Besides looking into packaged mailing list so ware, you can bypass the mail() func on and talk directly to your SMTP server via a socket connec on. Such an example is shown in the PHP manual for the fsockopen() func on (h p://www.php.net
9 trong 10
25/09/2013 2:06 PM
Articles
http://www.informit.com/articles/printerfriendly.aspx?p=1924985
/fsockopen), as well as in other developer resource sites. Q. Where do bounced messages go? A. As with any email (not just those sent in the manner described in this chapter), bounces go to whatever address you specify in your From: or Reply-to: mail headers.
Workshop
The workshop is designed to help you review what youve learned and begin pu ng your knowledge into prac ce.
Quiz
1. Which PHP func on sends mail? 2. Why is $mysqli named as a global variable in Lis ng 19.1? 3. What PHP func on call causes the script to execute for as long as it needs to run?
Answers
1. This is not a trick ques on. Its the mail() func on! 2. Because the variable $mysqli is created and assigned a value in a func on that is included in one script for use by another, the variable must be declared as global to ensure it is usable outside of the con nes of the func on in which it was created. 3. set_time_limit(0)
Ac vi es
1. Modify the manage.php script to display the users email as part of the response message for any ac on that is taken. 2. Modify the sendmymail.php script to add addi onal form elds that will correspond to sec on headings in the message string itself. Remember that when the form is submi ed, those strings will have to be concatenated into one message string that is sent to the mail() func on.
10 trong 10
25/09/2013 2:06 PM