Comments
No comments yet. You can be the first!
Posted by: JDS
Okay, so I have been tasked with making, basically, an MLM (Mailing List Manager). Well, the MLM is sorta broken into two parts -- the LIST management part, and the EMAIL creation and sending part. This article only discusses the email sending aspect.
I encountered a number of problems and solutions on this project, and I consider it a good, well-rounded example of small web application development. Small? Well, ultimately, it really is a pretty small project, but I did use a number of skills and techniquest to complete it. (Did I say "complete"? Hah! A Web application is never complete!)
Description of solution needed...
Well, the simple answer is "forking". But that turned out to be not really possible using PHP alone. PHP has some process forking tools, but they are only usable when using PHP in CLI mode. See the manual for (sketchy) details (http://us3.php.net/manual/en/ref.pcntl.php).
Okay, so PHP won't fork when running as a web server module. Or, at least, it won't work as advertised (it crashed the server when I tried it!). So I needed to create a system tool that I could then use with "exec()" or "system()" -- PHP system calls. Using those, I could put an ampersand at the end of the command and the Unix shell will do the forking. So I wrote a simple email sender in Perl, and used that. It really is quite basic! Here it is:
#!/usr/bin/perl
$TO_LIST_FILE = shift @ARGV;
$EMAIL_CONTENTS = shift @ARGV;
@to_list = get_to_list( $TO_LIST_FILE );
$message = get_message( $EMAIL_CONTENTS );
foreach $to ( @to_list ){
$message_out = $message;
$message_out =~ s/\@\@TO\@\@/$to/g;
sendEmail( $message_out );
}
unlink( $TO_LIST_FILE );
unlink( $EMAIL_CONTENTS );
sub get_message{
$out = '';
$filename = shift @_;
open(INFILE, $filename) or die "Can¿t open $filename: $!";
while (<INFILE>){
$out .= $_;
}
return $out;
}
sub get_to_list{
$filename = shift @_;
open(INFILE, $filename) or die "Can¿t open $filename: $!";
while (<INFILE>){
next if /^\s*$/;
chomp;
push @out, $_;
}
return @out;
}
sub sendEmail {
# Optional: put a sleep statement here to help reduce server load.
# sleep 1;
my $message = shift @_;
my $sendmail = '/usr/sbin/sendmail';
open(MAIL, "|$sendmail -oi -t");
print MAIL "$message\n";
close(MAIL);
}
A couple of minor points:
The Perl script takes 2 arguments: the full system path of a file containing a list of email addresses, and the full path to a file containing the preformatted email message. The message body needs to use a "mail merge" field in place of the "To:" in order for the Perl script to substitute each email address in the list. I also redirect STDER to /dev/null
It is important to realize that the Perl script is so closely dependent on the PHP script that they are, in many senses, components of the same script. I just wrote one small part in Perl, is all.
Also, this combination of scripts simply will not work on a Windows platform.
Also, also, one needs to have sendmail installed (and properly configured) for the actual mailing part.
I have an existing database of names and email addresses (and other things). I used that. I think the details are a little outside the scope of this article, though, except a mention that the email addresses are all used by putting them into an array.
Wow, this was a doozy. But fun. There are a lot of new things about this part that I had to learn. Also, I describe how to create HTML-formatted emails in this section, as the techniques to do that are the same as those used to create email attachments. Here are some of the details.
Of course, that's a lot of stuff. Maybe I should break this out into a separate article altogether!
Simple summary: get uploaded files, base-64 encode those files, create a properly-formatted email message including MIME attachment boundaries. Send this to mailer.
...details coming soon...
I still have a number of features to add. I also need to describe the list management part. Oh, if only I had time! Woe!
No comments yet. You can be the first!