Zyx's guide to mass e-mails in PHP

Had your computer crash on you, or a website shows wrong, or your printer went dead on you? Come on in...

Moderator: Crew

User avatar
Zyx
Pretender to the throne
Posts: 1909
Joined: Wed Mar 29, 2006 20:48
Location: Helsinki

Zyx's guide to mass e-mails in PHP

Post by Zyx »

Hi!

Today I'll show you how to easily make a script that will send a predefined HTML (HyperText MarkUp Language. No wait, that's HTMUL) electronic mail ("e-mail") message to a predefined set of people.

Today we'll focus on the back-end and maybe do a front-end for this later on.

Code: Select all

<html>
<head><title>Mass E-mailer From Hell</title></head>
<body>
<p>Processing... pray to whatever spiritual entity you're accustomed to.</p>
<?
# Mass-Emailer From Hell by Zyx

# NOTE: this either works or totally sucks.

# my guess is that the number of recievers limit is set at ISP-level, so we 
# probably need to send the mails in batches. Yes, one could impelement that as a for loop or similar here, but the docs said mail() might be a bit slow so I don't want to hit any timeouts.

# You probably want to GET or POST these variables.
$from = "The Monkey King <[email protected]>"; # either just e-mail or if you want to make it fancy, do it like that
$to = "[email protected], [email protected]"; # separate with commas (,)
$subject = "Monkeys represent, yo!";
$message = "<html><body><h1>Keep it real monkeymen</h1><p>Peace out.</p></body></html>"; # remember to escape html-attributes' quotation marks (you know, the '"'s in <a href="http://dontaskemhowtoescape.the.se">) as \". 

$headers = "X-Mailer: Mass-Emailer From Hell v0.0\r\n"; # note the linebreaks CRLF
$parameters = ""; # do not touch.

# the default From: is set somewhere in php.ini and we probably can't touch it (tii-di-di), so we do it like this:
$headers .= "From: ".$from."\r\n";

# php docs said this might be a good idea. f*** if I know this messes up the HTML. Remove in case of fire.
$message = wordwrap($message,70);

# php docs said this is the way to send HTML. Guess the charset should be checked. We get no spanking euro-chars with that biatch. That be iso-8859-15, yo. utf8 might be a good choice too.

$headers .= "MIME-Version: 1.0\r\n"; 
$headers .= "Content-type: text/html; charset=iso-8859-1\r\n";

# Oh, and by the way, this way we can send HTML, but not any attachments like images or stuff like that (we just link to them). I assumed we don't want to do that. If we want, then we're f***. Read next comments for more information. 

# For the PHP docs said:
# Note: If intending to send HTML or otherwise Complex mails, it is recommended to use the PEAR package. 

# ...but guess how much I know about PEAR or if our webhost happens to support PEAR::Mail_Mime

# The PHP docs also decided, later on, tell me that 
# Note: It is worth noting that the mail() function is not suitable for larger volumes of email in a loop. This function opens and closes an SMTP socket for each email, which is not very efficient. 
# For the sending of large amounts of email, see the » PEAR::Mail, and » PEAR::Mail_Queue packages.

# Well, duh, why the f*** do you have over-simplistic function built-in? One would imagine that in the 21st Century, people might want to send HTML, like, by default.

# Oh, and the guys who want plain text? I'll be kind to them in the next version. Promise.


if (!mail($to,$subject,$message,$headers,$parameters)) {
	echo "<h1>yay. it failed.</h1>";
} else {
	echo "<h1>yay. it just might've worked.</h1>";
}

echo "<br><b>For reference, this is was what we tried to send:</b>";
echo "<br>To: <code>" . htmlspecialchars($to);
echo "</code><br>From (you should see this below too): <code>" . htmlspecialchars($from);
echo "</code><br>Additional headers (besides what PHP and sendmail send):<br><code>" . nl2br(htmlspecialchars($headers));
echo "</code><br>Parameters (this better be empty): <code>" . $parameters;
echo "</code><br>Message (source):<br><code>";
echo htmlspecialchars($message);
echo "</code><br>";
echo "<br>Message (in crapped out html):<br>";
echo $message;
?>
</body>
</html>
Do notice the comment/code ratio. :thankyou:
Do you has what it takes to join the Homestarmy? The guts? The determination? The five bucks? Join today!
User avatar
Zyx
Pretender to the throne
Posts: 1909
Joined: Wed Mar 29, 2006 20:48
Location: Helsinki

Post by Zyx »

Welcome back!

Today we'll do some kind of a front-end for the code we did yesterday. Please do note that this will not work out-of-the-box for couple of reasons. The first one is that it seems that our (like most) ISP cuts off recepients somewhere around 30. Bypassing that is an advanced feature we'll add next.

Anyway, this is a nice little front-end where one can add a nice subject and message. All e-mail recepients are nabbed directly out of phpbb2's database.

Code: Select all

<html>
<head>
<title>Let's send some e-mails!</title>
</head>
<body>
<?
# Let's Send Members Some E-mail by Zyx

# Changelog
# v0 - Initial release

# This stuff makes it easy for me to access the database...
define('IN_PHPBB', true);
$phpbb_root_path = './';
include($phpbb_root_path . 'extension.inc');
include($phpbb_root_path . 'common.'.$phpEx);

# ...like this (I copied this from memberemail.php)
$SQL = 'SELECT user_email FROM phpbb_users WHERE user_id > 0 AND user_id != 2';
$result=$db->sql_query($SQL) or die("<h1>Yay! It failed!</h!><p>".$SQL.' '.mysql_error());
$rows = $db->sql_numrows($result); # Does this work? I've no idea. At least this will be broken in phpBB3, I guess.
while($row=$db->sql_fetchrow($result))
{
	$to.=$row['user_email'].',';
}
?>

<h1>Please fill all the fields correctly or <?= $rows ?> people will get angry</h1>
<form action="massemailer.php" method="post" accept-charset="iso-8859-1"> <? # I guess that charset should match the one in the mail headers ?>
<p>Subject: <input type="text" name="subject" size="70" value="">
<input type="hidden" name="from" value="Glorious Monkey King <[email protected]">
<br>Message:<br><textarea name="message" rows="10" cols="70"></textarea>
<input type="hidden" name="to" value="<?= $to ?>">
  </p><p><input type="submit" value="Continue &rarr;"></p>
</form>

</body>
</html>
Oh, and the second reason why no-one should go out and put these anywhere yet is that there's no authentication so pretty much anyone could harass our members. :spammer:
Do you has what it takes to join the Homestarmy? The guts? The determination? The five bucks? Join today!
User avatar
Chroelle
Admin emeritus
Posts: 9870
Joined: Fri Feb 17, 2006 9:19
Location: Location, location...

Post by Chroelle »

So can this work for us by now?
Currently testing Life version 2.9 (With added second child)
(Beta testing in progress)

www.paed-it.dk - My blog in Danish

Clothes make the man. Naked people have little or no influence on society.
--Mark Twain
User avatar
Chroelle
Admin emeritus
Posts: 9870
Joined: Fri Feb 17, 2006 9:19
Location: Location, location...

Post by Chroelle »

....?
Currently testing Life version 2.9 (With added second child)
(Beta testing in progress)

www.paed-it.dk - My blog in Danish

Clothes make the man. Naked people have little or no influence on society.
--Mark Twain