Category Archives: XHTML

Prevent contact form spam in WordPress with Contact Form 7 and Akismet


If you’re running WordPress and have a contact form on your website, there’s a good chance you’re using Contact Form 7. You can get away with using it as-is for a while, but as time goes on, spambots begin to find their way into your inbox.

At that point you have two options. You can deal with the spam via your:

  1. Website– prevent messages from ever being submitted.
  2. Inbox– tune your spam filter to delete those messages.

It seems logical to try and stop the messages as early as possible.

Most people would resort to something like CAPTCHA now, but I’m personally not a fan of it. I believe in keeping the user experience in tact for as long as I possibly can.

Enter Akismet, a service that can pretty reliably identify post comments containing spam. Luckily, what’s good for comments is also good for emails. It makes sense, too, because from a spambot’s perspective, both are submittable forms.

Continue reading

Monitor database availability with Pingdom


I’m testing out a new VPS with a couple sites on it, and after several hours of uptime, the mysqld service (database) was sacrificed in order to clear up RAM. As it turns out, I didn’t have a swap space for the VPS to offload inactive pages in memory.

I wrote about how to add a swap space to your VPS yesterday, but today I wanted to share how you can get alerted by Pingdom that your database is down. If you simply check for a 200 OK response, Pingdom would report that everything is OK, however if your site is database-dependent, just because the server is up doesn’t mean the site is functional.

Now, it is possible that you could have a database issue with one site, but not the other, in other words, you’d eventually want to monitor both sites using two different checks, however the goal here is to ensure that the database is generally available.

The following describes how you can setup a page on your VPS to report whether the database is up, and how you can then have Pingdom look for that information to determine whether your server is considered up.

Continue reading

Using the HTML5 video player for serving .ogv files in Firefox and Safari, and .mp4 files in Internet Explorer

I was working with a web page that used the following code to embed videos:

<video width="320" height="240" controls>
   <source src="videos/demo.ogv" type="video/ogg">

But they weren’t playing in Firefox, Safari or Internet Explorer — only Chrome.

Let’s break down the issues I encountered with each browser and how I solved them.

Issues with Safari

The problem with Safari was that the website was protected with Apache’s basic authentication:

AuthType Basic
AuthName "Password Protected"
AuthUserFile /var/www/
Require valid-user

To work around that issue, I moved the videos outside of the protected directory. I did this by reusing a virtual host I created a while back for assets i.e. Once I moved the videos and updated the HTML5 code:

<video width="320" height="240" controls>
   <source src="" type="video/ogg">

The videos played fine in Safari and Chrome.

Issues with Firefox

The problem with Firefox was the following error:

No video with supported format and MIME type found.

A quick search revealed that it was in fact because of a missing MIME type. To test this, I placed a .htaccess file in the web root with the following command in it:

AddType video/ogg .ogv

But it didn’t work. Then I realized that I wasn’t serving the videos from, but rather, So I placed the .htaccess file in the web root of and now the videos also played in Firefox.

As a side note, if you’ll be serving such files across multiple websites on your server, you should consider adding the MIME at the server level.

Issues with Internet Explorer

Internet Explorer displayed absolutely nothing (not even a video box with an X — more on that later). Turns out, IE9 or less does not support .ogv files. You’ll need an .mp4 version of your videos. Luckily, I was provided with those, so I modified the embed code to:

<video width="320" height="240" controls>
   <source src="" type="video/ogg">
   <source src="" type="video/mp4">

You should also double check that you have the following MIME type already setup:

AddType video/mp4 .mp4

Next I noticed that only one video played. Another quick search online revealed that those videos must use the H.264 codec. Unfortunately, only one of them used it; the others were MPEG-4.

You can easily find out what codec you’re using if you’re on a Mac:

  • Right-click on the video.
  • Choose Get Info.
  • Expand More Info.
  • Look under Codecs.

While I was doing this research, I found a neat way to troubleshoot those videos in Internet Explorer.

If you’re on the page with the broken videos:

  • Open Internet Explorer’s developer tools (F12).
  • Click on the Console tab.
  • Type in the following and hit ENTER:
  • If the first video on the page is not the video you’re having problems with, increment the index.
  • Visit this page for error code details.

That’s it. Once you get your videos converted, you should be good to go.

Issues with testing from a corporate network

In my instance, I was performing these tests from a corporate network. Turns out, all websites were automatically served in compatibility view, meaning that even though the one video had the right codec, it wasn’t playing. This is also why the video box was blank as apposed to showing an X.

I noticed that because of a message in developer tools:

HTML1202: is running in Compatibility View because ‘Display intranet sites in Compatibility View’ is checked.

That was a tricky one, because I almost didn’t see that. The way you can try to get around that is as follows:

  • Click on the settings gear toward the top right.
  • Choose Internet options.
  • Click on the Security tab.
  • Click on the Local intranet icon.
  • Click on the Sites button.
  • Click on the Advanced button.
  • Select the appropriate website and click Remove.
  • Don’t forget to put that entry back later 😉

I should point out that your changes may not be saved, depending on the network policy. It’s also a very good idea to check with your help desk, since this is a legitimate requirement, and therefore they may be able to offer an alternative such as creating a local computer account.

If you have any questions about any of the troubleshooting steps I wrote about, feel free to ask in the comments below.

Send and receive binary files using PHP and cURL

I was recently working on a project where I had to send and receive binary files to and from a REST API, so I decided to document some of the code I wrote. Keep in mind that I’m extracting all of these code snippets from a custom PHP class I wrote, so if you’re working with an API, I’d encourage you to create a class of your own.

Setup a form to submit a file

Before you can send a binary file to an API, you have to get it from somewhere. In my project that file came from a form. The form could be as simple as this:

<form method="post" action="index.php" enctype="multipart/form-data">
	<input name="file" type="file" />
	<input type="submit" value="Upload" />

Note the enctype attribute is set to multipart/form-data. You must have this set, otherwise the file will not be submitted.

Grab the submitted file

Normally when you process a form, the contents are found inside of the global $_POST variable, however file data is located within the global $_FILES variable.

If you print out the contents of $_FILES on the page the form was submitted to, you’d see something like:

    [file] => Array
            [name] => Array
                    [0] => 400.png
            [type] => Array
                    [0] => image/png
            [tmp_name] => Array
                    [0] => /tmp/php5Wx0aJ
            [error] => Array
                    [0] => 0
            [size] => Array
                    [0] => 15726

What’s unusual about this array is that instead of grouping each file’s data in one array, each piece of information about a file is grouped together. So the values at index 0 in name, type, tmp_name, error and size belong to one file.

The binary file data is located in a temporary storage on your server. In this case, at /tmp/php5Wx0aJ.

Send the binary contents via cURL

The following snippet sends the binary file to a URL:

$url = '';
$header = array('Content-Type: multipart/form-data');
$fields = array('file' => '@' . $_FILES['file']['tmp_name'][0]);
$token = 'NfxoS9oGjA6MiArPtwg4aR3Cp4ygAbNA2uv6Gg4m';

$resource = curl_init();
curl_setopt($resource, CURLOPT_URL, $url);
curl_setopt($resource, CURLOPT_HTTPHEADER, $header);
curl_setopt($resource, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($resource, CURLOPT_POST, 1);
curl_setopt($resource, CURLOPT_POSTFIELDS, $fields);
curl_setopt($resource, CURLOPT_COOKIE, 'apiToken=' . $token);
$result = json_decode(curl_exec($resource));

Let’s talk about each of these lines, because some of this will depend on the requirements of the API you are using and may not be necessary.

  • $url is where cURL will post your data.
  • $header tells the API that there is a file coming its way. You can supply more headers by adding additional values to the array.
  • $fields contains an associative array. The field name depends on what the API expects it to be. The @ sign in the value tells cURL that we’re dealing with a file.
  • $token is a token that the REST API expects as a cookie. Usually you login to the API once during a transaction, then use a token for all subsequent requests. The cookie is called apiToken, but this may differ depending on the API’s expectations.
  • CURLOPT_RETURNTRANSFER tells cURL we want a response.
  • CURLOPT_POST tells cURL we want our data to be posted.
  • CURLOPT_COOKIE sets the token as a cookie.

Lastly, notice the last line:

$result = json_decode(curl_exec($resource));

In my case I know that the response I’m getting from the API will be in the JSON format, which is why I’m decoding it. You may not need this if you’re getting back a response in XML, for example.

This completes sending a binary file via cURL. Next we’ll look at retrieving that file.

Retrieve the binary contents via cURL

Here’s how to retrieve a binary file:

$resource = curl_init();
curl_setopt($resource, CURLOPT_URL, $url);
curl_setopt($resource, CURLOPT_HEADER, 1);
curl_setopt($resource, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($resource, CURLOPT_BINARYTRANSFER, 1);
curl_setopt($resource, CURLOPT_COOKIE, 'apiToken=' . $token);
$file = curl_exec($resource);

We don’t have to go over anything except for:

  • CURLOPT_HEADER tells cURL that we expect there to be a header. This is important because it tells us what kind of file we’re getting i.e. an image, a Word document, a PDF, etc.
  • CURLOPT_BINARYTRANSFER tells PHP that the result will contain binary data. Lots of people claim you don’t need this line. I say try it with and without, just to be sure.

Now you have the binary file with its headers stored in $file.

Give the file back to the user

Let’s go over on how to give the file back to the user. You could either store the file on the server and give the user a path to the file, or you can just let PHP handle all that on the fly and simply prompt the user to save the file.

Here is how I did that:

$file_array = explode("\n\r", $file, 2);
$header_array = explode("\n", $file_array[0]);
foreach($header_array as $header_value) {
	$header_pieces = explode(':', $header_value);
	if(count($header_pieces) == 2) {
		$headers[$header_pieces[0]] = trim($header_pieces[1]);
header('Content-type: ' . $headers['Content-Type']);
header('Content-Disposition: ' . $headers['Content-Disposition']);
echo substr($file_array[1], 1);
  • On line 1 I separate the header from the rest of the file.
  • On line 2-8 I parse the header contents and put them in an array so I can easily reference the elements I need.
  • On line 9 &10 I tell PHP what the content type is and what the file should be called.
  • On line 11 I output all of the binary contents. Together with the header, it prompts the user to save the file (or displays it in the browser if it’s an image, for example).

I want to touch on the function on line 11: substr($file_array[1], 1);

In my case the binary file had an extra space at the beginning of the file. The substr function removes that. I’m not sure whether that space came from the API or from the explode on line 1, so if this doesn’t work for you, try changing that line to: echo $file_array[1];

Hopefully this info will shed some light on how to post and retrieve files in a binary format. If you have any questions, leave them in the comments below.