The PHP Base64 encode and decode functions

PHP FAQ: Can you share an example of the PHP Base64 encode and decode functions?

Every once in a while when you're working on a web application you'll run into data that can cause you some problems, and when that happens, the PHP base64_encode function can come to your rescue. Here's a quick look at a problem I ran into yesterday using CakePHP, and how the PHP base64_encode and base64_decode functions helped me encode a URL (URI) and bail me out of my predicament.

My PHP URL (URI) problem

Correction: While this article shows how to properly call the PHP Base64 encode and decode functions, the basic premise of removing the "/" characters from the URL, as discussed next, is not correct. The PHP base64 encode algorithm can return a string with the "/" character in that string. Please see the Comments section below for the correction for this problem.

I was working on a CakePHP web application yesterday when I ran into an unusual problem: I was displaying data in a table in an index page, and I wanted to turn one of the columns of text into a hyperlink to a detail page. But when I went to make the column a hyperlink, I realized I didn't have something like an id field I could use as a parameter to my CakePHP controller call.

In fact, because of the data at hand, the only thing I had was a string -- and that string happened to be a URI (i.e., something like /foo/bar/baz). As you might guess by looking at it, trying to pass a raw URI string to a controller (with characters in it like the forward-slash character("/")) would have driven CakePHP nuts.

I knew I couldn't change the data, and I knew I needed to pass that URI string to the CakePHP controller, when I remembered my friend, the PHP base64_encode function, and the PHP URL encode technique.

PHP URL encoding - base64_encode to the rescue

In short, the PHP URL encode technique involves encoding a URL (or URI) before submitting it in an HTML form, and then decoding the URL after it has been received by whatever controller you are submitting your form to.

In the case of my CakePHP problem, I used the PHP base64_encode function in my CakePHP view page, and encoded my URI string as shown in this CakePHP code snippet:

<td>
<?php echo $html->link($logfileRecord['LogfileRecord']['uri'], 
           array('controller'=>'website_nodes', 
           'action'=>'uri_details',
           base64_encode($logfileRecord['LogfileRecord']['uri']))); ?>
</td>

As you can see in that example, I encode my URL/URI string with the PHP base64_encode function before passing the string to my CakePHP controller method (uri_details).

PHP base64_decode in the controller

Of course that's only half of the solution. If you encode a string on one end (the view), you'll need to decode it on the other end (the controller), and that's where the PHP base64_decode function comes in.

Again, this is very simple. Just use the PHP base64_decode function in the controller to convert the encoded string back to its original content with the base64_decode function, like this:

// decode the uri back to its original form
$uri = base64_decode($uri);

That's all there is to it, problem solved.

More PHP base64 encode and decode information

Before leaving, here's some quick documentation from the PHP base64_encode function manual page:

Encodes the given data with base64. This encoding is designed to make binary data survive transport through transport layers that are not 8-bit clean, such as mail bodies.

As you can see from that description, the way I'm using the PHP base64 encode and decode functions isn't exactly the intended use for these functions, but it does work very well, and I know many developers that use this technique whenever they run into this sort of problem.

Finally, here's a little more information about the PHP base64 encode and decode functions, and Base64 encoding in general:

Permalink

It seems that not many people realize that base64_encode() function sometimes returns '/' and '+' which could, happily, break your url. The solution, replace those *bad* characters:

function b64($string, $decode = false)
{        
  return $decode ? base64_decode(strtr($string,'-_,','+/=')) : strtr(base64_encode($string), '+/=', '-_,');
}

Thank you for your clarification/correction, and code. I just read the Wikipedia Base64 page more carefully, and the last two encoding characters (values 62 and 63) of the MIME Base64 character set are the '/' and '+' characters. The PHP function appears to use the MIME encoding algorithm, so yes, they can return '/' and '+', and the '/' would be really bad for my example.

There is also a discussion on the Wikipedia page about this issue:

Using standard Base64 in URL requires encoding of '+' and '/' characters into special percent-encoded hexadecimal sequences ('+' = '%2B' and '/' = '%2F'), which makes the string unnecessarily longer.

For this reason, a modified Base64 for URL variant exists, where no padding '=' will be used, and the '+' and '/' characters of standard Base64 are respectively replaced by '-' and '_', so that using URL encoders/decoders are no longer necessary and have no impact on the length of the encoded value, leaving the same encoded form intact for use in relational databases, web forms, and object identifiers in general.

Thanks again for your correction. I'll make a note of this in the article.

Add new comment

The content of this field is kept private and will not be shown publicly.

Anonymous format

  • Allowed HTML tags: <em> <strong> <cite> <code> <ul type> <ol start type> <li> <pre>
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.