Hello, dear internet. It’s been a while.
First of, I would like to apologize for the long delay, I promised [myself] I would publish this article a while ago, but in the end, I was never able to find the time. This is because I have been working in an online multiplayer game enthusiastically. The game’s demo is almost done, and I’m really exited about it! I hope it will see the light pretty soon :) But back to the topic!
Recently, I found a question in LinkedIn, asking how to implement a mailing service in PHP. That really brought me back to the old times, when I first did such a thing years ago.
Sending mail in PHP is pretty straight forward, and something every web developer should know. You will be needing a few things:
- A PHP page with a form to collect mailing data, and its backend.
- A database table to store the user data
- Another db table, to store mailing data
- A PHP page to send the emails
- A job that executes the PHP page periodically
Before going on, you can grab the source from github, should help you follow the tutorial more smoothly.
First of, we will create the database table. Database tables have an added value: once you’ve decided how the table should be, you can forget about the requirements a bit, and just write code that follows the db logic.
The weapon of choice here is usually phpMyAdmin, the most widely adopted MySql design tool. It’s extremely simple to use, and hosting services usually include it in the package. With it, you can import mailing_tutorial.sql if you wish, though I’d suggest you just take a look at the general structure, it’s quite simple.
I’ll assume you already have a users table, that holds some basic information, such as name, gender, and obviously email address.
Let’s see the mailings.new.ui.php file first. Plain old form, really simple. What about mailings.new.post.php? Not much magic going on here, it just takes the POST and inserts it into the db. The only thing that might stand out a bit are the queries SET NAMES ‘utf8’ and SET CHARACTER SET ‘utf8’: it’s important to use the same encoding everywhere. If you open these .php files in Notepad++, you’ll also notice they are also encoded in utf8 without BOM, and the html is declared to use that charset. You may need to set up Apache (or whatever server you’re using) to serve files in UTF-8. Of course you can chose any charset/encoding you wish, but it’s important to maintain consistency, otherwise things will break somewhere and you might end up emailing broken characters.
Since we want the mails to be sent automatically, we need some kind of scheduler. But php pages are run on demand, how can we do that in php!? Long story short: you can’t, you need a workaround. Under Linux, that workaround is called Cron, under Windows, it’s the Scheduler. But we well talk about those later. First, we need a php page that handles the actual mailing. That’s mailing.send.php and it should look something like this:
$queryMail = mysql_query(“select * from mails where SendDate >= now() and Sent != 1 order by SendDate asc limit 1″);
$queryUsers = mysql_query(“select * from users”);
while ($user = mysql_fetch_array($queryUsers))
@mail(user[“emailAddress”], mail[“subject”], mail[“body”]);
Let’s see: first, we’re retrieving one mailing for the db. We’re selecting the one that is ready to be sent, and has not been sent already. This query may return zero rows, in which case all mailings have been sent, or there were no mailings in the database at all.
Afterwards, we’re retrieving all users, and looping through them, sending an individual email to each one.
About the mail() function, notice that Linux servers usually come with an SMTP installed so you can use it as it comes, but in Windows, the mail() function will fail unless you set it up yourself, but that’s unnecessary in most cases.
Bottomline, that page will take care of sending the first email in the queue to all users, whenever “visited”. That is, if you write the url to that file in the browser and hit enter, it will start sending mails. We need that part done automagically, so let’s set up a Cron job to “run” the page.
Most likely, you’ll be doing this through a cPanel, which should allow you to easily set up a cron job under the Advanced tab. Just fill out the date and time of your wishing, just remember a star (*) means “every”. That is, if you fill a star under day, it will run every day. And under command, you’ll need to fill something like
/usr/local/bin/php /home/john/mailing.send.php, where the first part is the path to the binary that will get executed, in our case, the php compiler; and the second is the argument cron will pass to the binary, in this case, the path to our mailing.send.php file. If you’re unsure about the php binary path, try asking your hosting service. To know the actual full path to the .php file, you can add a
echo __FILE__; line to it.
This is a fairly simple mailing, if you think you will be sending many mails (say, over 10k/month), you might like to try an email marketing tool instead. They are much more reliable and have higher delivery rates, among many other advantages.
Also, the mysql_query etc functions are deprecated, I included them just as an example. If you’re not using any framework for the db related stuff, consider Choosing a MySQL API.
Last but not least, this example doesn’t say anything about actual lists, it just sends the mails to all users. That is completely valid for small, simple websites such as an artist’s portfolio; but if you need more horsepower, there’s a little more work to do. Adding a condition such as where user.newsletterDisabled = false in the mysql query, or creating a whole new mailinglists table that matches user id’s to mailing lists id’s, and adding a mailinglistId field to the mailings table, are just some ideas. The rest is up to you.
I hope this article helped you, and as always, feel free to ask any questions that come to mind: I’ll be glad to further help you, and better this article. See you in the next post, and good coding! :)