Sunday, August 25, 2013

URL Encode in JS URL decode in PHP

Recently I had a task where I needed to find a Javascript function that would mimic the PHP urlencode function.

The first thing I tried was encodeURIComponent(). This turns spaces into %20, single-quotes into %27 or something like that. So I did a search and found these out-of-the-box options for URL encoding in Javascript:

  • escape() will not encode: @*/+
  • encodeURI() will not encode: ~!@#$&*()=:/,;?+'
  • encodeURIComponent() will not encode: ~!*()'
Encoded test string: "Jimmy's Coffee & Bean Emporium":

In Javascript using encodeURIComponent()
Jimmy's%20Coffee%20%26%20Bean%20Emporium
In Javascript using escape()
Jimmy%27s%20Coffee%20%26%20Bean%20Emporiu
In Javascript using encodeURI()
Jimmy's%20Coffee%20&%20Bean%20Emporium
In PHP using urlencode()
Jimmy%27s+Coffee+%26+Bean+Emporium

None of the encoded strings are the same.

The solution:

I created a new Javascript function called php_urlencode() to encode the same way PHP does.

function php_urlencode(str) {
    return escape(str).replace(/\+/g,'%2B').replace(/%20/g, '+').replace(/\*/g, '%2A').replace(/\//g, '%2F').replace(/@/g, '%40');
}
This function uses the escape function first and then uses the "replace()" regular expression function to replace a few strings with something PHP would use instead. It uses the "/g" global replace property to replace all instances of the string instead of just the first one.

  • + becomes %2B (done first to encode valid "plus" symbols)
  • %20 becomes + (done after the first to turn spaces into the "plus" symbol)
  • * becomes %2A
  • / becomes %2F
  • @ becomes %40

This function returns:
Jimmy%27s+Coffee+%26+Bean+Emporium
In PHP using urlencode()
Jimmy%27s+Coffee+%26+Bean+Emporium

It matches! Very nice.