views:

3066

answers:

4

I'm POSTing the contents of a form field via AJAX to a PHP script and using Javascript encode(field_contents). The problem is that any plus signs are being stripped out and replaced by spaces. How can I safely 'encode' the plus sign and then appropriately 'decode' it on the PHP side?

A: 

Try

encodeURIComponent()

in JS and

html_entity_decode($_POST['field'],ENT_NOQUOTES,'UTF-8');

In PHP

Deniss Kozlovs
encodeURIComponent is the right answer — but as it generates URL encoded data and not HTML encoded data, html_entity_encode is way off.
David Dorward
+2  A: 

The hexadecimal value you are looking for is %2B

To get it automatically in PHP run your string through urlencode($stringVal). And then run it rhough urldecode($stringVal) to get it back.

If you want the JavaScript to handle it, use escape( str )

Edit

After @bobince's comment I did more reading and he is correct. Use encodeURIComponent(str) and decodeURIComponent(str). Escape will not convert the characters, only escape them with \'s

Rob Allen
*Don't* use `escape` (or `unescape`) in JavaScript; they aren't the same as URL-encoding and will go wrong for + and any non-ASCII Unicode characters. encodeURIComponent/decodeURIComponent is almost always what you want.
bobince
+3  A: 

Use encodeURIComponent() in JS and in PHP you should receive the correct values.

Note: When you access $_GET, $_POST or $_REQUEST in PHP, you are retrieving values that have already been decoded.

Example:

In your JS:

// url encode your string
var string = encodeURIComponent('+'); // "%2B"
// send it to your server
window.location = 'http://example.com/?string='+string; // http://example.com/?string=%2B

On your server:

echo $_GET['string']; // "+"

It is only the raw HTTP request that contains the url encoded data.

For a GET request you can retrieve this from the URI. $_SERVER['REQUEST_URI'] or $_SERVER['QUERY_STRING']. For a urlencoded POST, file_get_contents('php://stdin')

NB:

decode() only works for single byte encoded characters. It will not work for the full UTF-8 range.

eg:

text = "\u0100"; // Ā
// incorrect
escape(text); // %u0100 
// correct
encodeURIComponent(text); // "%C4%80"

Note: "%C4%80" is equivalent to: escape('\xc4\x80')

Which is the byte sequence (\xc4\x80) that represents Ā in UTF-8. So if you use encodeURIComponent() your server side must know that it is receiving UTF-8. Otherwise PHP will mangle the encoding. PHP5 supports UTF-8 natively, it is only PHP4 that is the real problem.

bucabay
One follow-up: When I encodeURIComponent(text) and text includes characters like the smart quote (), the php script seems to see junk characters. I assume it's a charset problem, but I don't know how to resolve it. I'm doing the AJAX POST with "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", and I'm using PHP5 on the server side.
jalperin
How are you viewing these characters? You have to make sure the browser knows it is UTF-8. In HTML you can set `<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">` or `<meta charset="UTF-8">` you can also set it in PHP with the Content-Type HTTP Header. `header('Content-Type: text/html;charset=UTF-8');` PS: does not decode in the browser (FF3.5).
bucabay
A: 

so what is best solution?

@Deniss Kozlovs answer doesn't work correctly!

deniz