Search code examples
phpactionscript-3urlencodeurldecode

Differences between PHP's urldecode and AS3's unescape?


PHP uses urlencode and urldecode while Actionscript 3 uses escape and unescape for encoding and decoding strings into a URL-safe format, but the problem is that apparently they aren't quite exactly the same. This causes problems for me occasionally when I try to use urlencode on a string in PHP and then unescape it in AS3, or escape in AS3 and urldecode in PHP. Does anyone know what the exact differences are? I found this post which lists the following differences:

**PHP urlencode**
á=%E1
é=%E9
í=%ED
ñ=%F1

**AS3 escape**
á=%C3%A1
é=%C3%A9
í=%C3%AD
ñ=%C3%B1

Are there more differences? Neither the official documentation for PHP nor the documentation for AS3 list what characters are encoded into what.


Solution

  • Well I did some testing, and the differences are substantial, even just for character codes 0 through 255. Here's my test code:

    **AS3**
    for (var i:uint=0; i<=255; i++) {
        var s:String = String.fromCharCode(i);
        trace(i + ": " + escape(s));
    }
    
    **PHP**
    for ($i=0; $i<=255; $i++) {
        $s = chr($i);
        echo $i . ': ' . urlencode($s);
        echo "\n";
    }
    

    After comparing the outputs, there are the following differences:

    char code 32 ( )
    AS3 escape: %20
    PHP urlencode: +
    
    char code 42 (*)
    AS3 escape: *
    PHP urlencode: %2A
    
    char code 43 (+)
    AS3 escape: +
    PHP urlencode: %2B
    
    char code 47 (/)
    AS3 escape: /
    PHP urlencode: %2F
    
    char code 64 (@)
    AS3 escape: @
    PHP urlencode: %40
    

    PHP also has rawurlencode, which turns a space into %20 instead of a + sign, but all the other differences remain. Beyond character code 255, AS3 adds an extra %u01 in front of things, which is not present in urlencode.

    Additionally, it seems that AS3 does have a way to URL-encode in the same manner that PHP expects, but you just can't access it normally.

    var symbols:String = " *+/@";
    var vars:URLVariables = new URLVariables();
    vars.param1 = symbols;
    trace(vars.toString()); // param1=%20%2A%2B%2F%40 <--- This is the same as PHP
    trace(escape(symbols)); // %20*+/@                     but not this
    trace(encodeURI(symbols)); // %20*+/@                  or this
    trace(encodeURIComponent(symbols)); // %20*%2B%2F%40   or this