The admin code I created worked fine except for one bothersome thing. It would send out the email to multiple recipients and print the proper unsubscribe code, BUT the "From" mail header did not work the way it should have inside of the "all" loop. It should have been printing my from email address on every email address, however it was printing "nobody" instead. When I send the emails to any single person the header it printed correctly. Do you know what I was doing wrong? Read on and I'll explain.
The Admin PHP code for the mail list script
Yesterday we did the HTML form and I realized while re-reading my diary entry I neglected to explain the "test" email and its use. You could set up an email and then mail to the "test" email first (you, namely). It is pretty good idea to run a test mail to see how things look before actually sending the email to multiple recipients. Unfortunately we are in a spam-filled cyber world these days. Let's look at the entire admin code to send the mail to multiple recipients. It is quite similar to the loop yesterday which filled the dynamic dropdown select menu:
<HTML>
<BODY>
<?
require("setup.php3");
if($contents == "")
{
print("Error, no comments were submitted");
exit;
}
$contents .= "\n ------------------------------------------------- ";
$contents .= "\n This email is not spam. You signed up for this ";
$contents .= "\n opt-in email list at http://www.php-scripts.com ";
$contents .= "\n If you would like to unsubscribe from this opt-in ";
$contents .= "\n list, just click the hyperlink below:\n";
if($to == "ALL")
{
$toemails = file("$mail_list_path/YOUR_EMAIL_LIST.txt");
sort($toemails);
print("Sending email to...<br><strong>");
for($index = 0; $index < count($toemails); $index++)
{
$y = $contents;
$y .= "\n http://www.php-scripts.com/php_diary/unsubscribe.php3?ID=$toemails[$index]";
$toemails[$index] = ereg_replace("\n", "", $toemails[$index]);
mail($toemails[$index], $subject, $y, $from_header);
print("$toemails[$index]</strong>...<strong>");
}
print("</strong>DONE");
}
else
{
// mail to only one recipient $to email address
$contents .= "http://www.php-scripts.com/php_diary/unsubscribe.php3?id=$to";
mail($to, $subject, $contents, $from_header);
print("Sending email to...<strong>$to</strong>...DONE");
}
$text = "<p>Email message sent was<br>$contents";
print(nl2br($text));
?>
</BODY>
</HTML>
Notes: I use the $y variable to show the unique unsubscribe url for each email. I could not simply append the $contents variable like I do when mailing to only one email because the second and subsequent emails in the loop would have a bunch of urls from other people tacked at the end. The $y variable will be reassigned with each loop and thus be unique for each email. Using the $contents .= I append the "this is not spam" default message to the end of the $contents message to each email with the appropriate link to unsubscribe from the list (generated from inside the loop). I didn't have to sort the emails before I sent them, but I chose to do it to make it easier to follow who got sent what emails. After doing a mailout you could print this page and file it away so you knew what you mailed to who. Quite handy reference, I think. Another PHP script could be written also to track what mails were sent to what recipients. Lastly, you will note a new and quite useful function called nl2br which replaces any new line (\n) with a <BR> HTML tag.
This completes construction of the mail list script. In review: we have the form that subscribes and unsubscribes people to the list, and the secure browser-based admin form to send mail to one recipient or to all. Admittedly, this is a very basic set of scripts, but it functions very well and shows the process of building a mail list program using PHP from the ground up. It also illustrates the process of building almost any php script. First you plan the HTML, then you insert the PHP code where necessary. Unlike Perl, you can weave in and out of HTML quite conveniently, so it makes a lot of sense to build your HTML design first and do the PHP coding last. It would be pretty easy, for instance, to add multiple mail lists to the admin area. That way you could first choose which email list you wanted to mail to, and second send the list out.
Now what was I stumped over?
The addition of the ereg_replace function was needed to remove the new lines from each email address as it was cycled through the "ALL" loop. Those new lines were fouling up the mail function, because new lines are how the headers are separated. ereg_replace is a case-sensitive match and replace whereas eregi_replace is case INsensitive match and replace. We will certainly be using these functions more in the future.
Please vote on what you think of this diary lesson :)
I received an email yesterday about using Windows with PHP and it prompted me to realize I haven't talked about PHP and portability between UNIX and Windows yet. My primary testing environments are all UNIX based, you should probably know, and although my code examples haven't been tested on Windows, I see no reason why they shouldn't work. Please let me know if you find out otherwise and I can add the Windows alternative in. At any rate I know of one resource you can look to for getting PHP configured on a Windows server:
http://www.imatix.com/html/xitami/index.htm - The Xitami server works well with PHP, is well documented, and is freeware, and it even can run Perl scripts too!
Y2k-related issues kept me busy today so not much time for self study. Although I want to get into searching next, so look for information on searching external urls to either pop up here later today or over the next few days.
Please vote on what you think of this diary entry :)
Miss me yesterday? lol :) I got a few emails saying, "I can't see the diary entry." The reason you couldn't see one is because there wasn't one :) I am going to try and study PHP every day until I feel that I no longer need to study aloud and online. I work some days in excess of 15 hours and have no time to study, so if you see no diary entry, I either didn't learn anything new or I didn't study that particular day. Whenever I write something, I do it in a sense *live* therefore you shortly after I code the HTML and hit save, my FTP editor FTPs these changes immediately onto the website. I suppose I could just add an entry to say hello or something, or ramble aloud about what I ate for the day, but I think you would grade me down on the useful rating scale considerably if I did do that. Who knows, though? I may do that once in awhile. Anyway, the readership of these diary entries is increasing, according to my access logs, and I thank you for tuning in, so to speak. How long these diary entries continue will be in direct proportion to the learning I do, and the number of email requests I get to explore PHP further. Please take a minute and use the form to send me ideas for future diary entries, if you would like to see me explore a new topic, or an existing one in greater depth. I have learned a great deal already and have started several new PHP scripts projects that will show up as full script downloads in the future. With the information in these diary entries, you should have been able to start some PHP projects of your own, as well :)
Searching website URLS
This diary is starting to grow with information and some type of search engine would be useful to allow people to get directly and quickly to the information they are interested in. In some ways a linear approach would be best (starting along with me at the beginning of the diary and moving through in chronological order, since this is an evolving website based on my learning in stages) and also since I have split my learning over several days. I wish I had more time to make a full lesson per day to keep this more cohesive, but such is the life of a true and yet (relatively) unedited diary. At any rate, if I wanted to find out about searching using PHP and wanted to get to it fast, a search engine in some capacity would be a nice feature for you (and me, in the future actually, when I need to reference back to something). Well that's what I'm working on next. PHP offers a pretty convenient way to search an entire page. How good is your memory? Let's write a quick script to search New Year's Day's diary entry for keywords. First, of course we need a search box:
Example #20: Simple search for keyword at a URL
Nothing fancy needed for this beginning example. I have linked the box above to the script code I'm about to show you. Go ahead (no looking back and cheating now) and type a word or two you think was probably contained in that HTML page. All the script does is tell you whether or not it is there and how many times the search criteria appeared on each line of HTML. Here's the code to do this:
<html>
<body>
<?
$size = 0;
$url = "http://www.php-scripts.com/php_diary/010100.php3";
$the_page = fopen($url, "r");
while(!feof($the_page))
{
$each_line = fgetss($the_page, 255);
if(eregi($search_criteria, $each_line, $results))
{
// for each line where there is a match, increment a counter
$size++;
}
}
fclose($the_page);
print("I found $size ocurrences of $search_criteria at $url");
?>
</body>
</html>
The script above, although rudimentary, illustrates scanning an internal or external website URL. Another and maybe faster (I haven't done a benchmark test, so I am not sure) way of doing an internal (or local) search would be to simply open the file using the file command, fill an array and then check each item in the array. You just replace $url with the actual URL you want to search. Of special note is the function fgetss which is slightly different than fgets. With fgetss PHP attempts to remove any HTML or PHP code before matching. Again you could substitute eregi with ereg and thus have a case sensitive search. Therefore, it would be quite easy to create a branch of code that checked whether the search should be for exact matches or "similar" matches, the case being the identifier. Add a dropdown menu to your search form box with the name of "type" and then pass the value of "exact" for case sensitive matches. You would then modify the above code to read:
$each_line = fgetss($the_page, 255);
if($type != "exact"
{
if(eregi($search_criteria, $each_line, $results))
{
// for each line where there is a match, increment a counter
$size++;
}
}
else
{
// ok let search using CASE SENSITIVE matches only
if(ereg($search_criteria, $each_line, $results))
{
// for each line where there is a match, increment a counter
$size++;
}
}
Please vote on what you think of this diary entry :)
<form method="POST" action="example20.php3"><p><input type="text" name="search_criteria" size="20">
<input type="submit" value="Search!"></p>
</form>
discuss this topic to forum
