Use PHP functions in JavaScript

JavaScript parse_str

Parses GET/POST/COOKIE data and sets global variables

1
2
3
4
56
7
8
9
1011
12
13
14
1516
17
18
19
2021
22
23
24
2526
27
28
29
3031
32
33
34
3536
37
38
39
4041
42
43
44
4546
47
48
49
5051
52
53
54
5556
57
58
59
6061
62
63
64
6566
67
68
69
7071
72
73
74
7576
77
78
79
8081
82
83
84
8586
87
88
89
9091
92
93
94
9596
function parse_str (str, array){
    // Parses GET/POST/COOKIE data and sets global variables  
    // 
    // version: 1008.1718
    // discuss at: http://phpjs.org/functions/parse_str    // +   original by: Cagri Ekin
    // +   improved by: Michael White (http://getsprink.com)
    // +    tweaked by: Jack
    // +   bugfixed by: Onno Marsman
    // +   reimplemented by: stag019    // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
    // +   bugfixed by: stag019
    // -    depends on: urldecode
    // +   input by: Dreamer
    // +   bugfixed by: Brett Zamir (http://brett-zamir.me)    // %        note 1: When no argument is specified, will put variables in global scope.
    // *     example 1: var arr = {};
    // *     example 1: parse_str('first=foo&second=bar', arr);
    // *     results 1: arr == { first: 'foo', second: 'bar' }
    // *     example 2: var arr = {};    // *     example 2: parse_str('str_a=Jack+and+Jill+didn%27t+see+the+well.', arr);
    // *     results 2: arr == { str_a: "Jack and Jill didn't see the well." }
    var glue1 = '=', glue2 = '&', array2 = String(str).replace(/^&(.*)$/, '$1').replace(/^(.*)&$/, '$1').split(glue2),
    i, j, chr, tmp, key, value, bracket, keys, evalStr, that = this,
    fixStr = function (str) {        return that.urldecode(str).replace(/([\\"'])/g, '\\$1').replace(/\n/g, '\\n').replace(/\r/g, '\\r');
    };
 
    if (!array) {
        array = this.window;    }
 
    for (i = 0; i < array2.length; i++) {
        tmp = array2[i].split(glue1);
        if (tmp.length < 2) {            tmp = [tmp, ''];
        }
        key   = fixStr(tmp[0]);
        value = fixStr(tmp[1]);
        while (key.charAt(0) === ' ') {            key = key.substr(1);
        }
        if (key.indexOf('\0') !== -1) {
            key = key.substr(0, key.indexOf('\0'));
        }        if (key && key.charAt(0) !== '[') {
            keys    = [];
            bracket = 0;
            for (j = 0; j < key.length; j++) {
                if (key.charAt(j) === '[' && !bracket) {                    bracket = j + 1;
                }
                else if (key.charAt(j) === ']') {
                    if (bracket) {
                        if (!keys.length) {                            keys.push(key.substr(0, bracket - 1));
                        }
                        keys.push(key.substr(bracket, j - bracket));
                        bracket = 0;
                        if (key.charAt(j + 1) !== '[') {                            break;
                        }
                    }
                }
            }            if (!keys.length) {
                keys = [key];
            }
            for (j = 0; j < keys[0].length; j++) {
                chr = keys[0].charAt(j);                if (chr === ' ' || chr === '.' || chr === '[') {
                    keys[0] = keys[0].substr(0, j) + '_' + keys[0].substr(j + 1);
                }
                if (chr === '[') {
                    break;                }
            }
            evalStr = 'array';
            for (j = 0; j < keys.length; j++) {
                key = keys[j];                if ((key !== '' && key !== ' ') || j === 0) {
                    key = "'" + key + "'";
                }
                else {
                    key = eval(evalStr + '.push([]);') - 1;                }
                evalStr += '[' + key + ']';
                if (j !== keys.length - 1 && eval('typeof ' + evalStr) === 'undefined') {
                    eval(evalStr + ' = [];');
                }            }
            evalStr += " = '" + value + "';\n";
            eval(evalStr);
        }
    }}
external links: original PHP docs | raw js source

Examples

» Example 1

Running

1
2
var arr = {};
parse_str('first=foo&second=bar', arr);

Should result in

1
arr == { first: 'foo', second: 'bar' }

» Example 2

Running

1
2
var arr = {};
parse_str('str_a=Jack+and+Jill+didn%27t+see+the+well.', arr);

Should result in

1
arr == { str_a: "Jack and Jill didn't see the well." }

Dependencies

In order to use this function, you also need:

Open syntax issues

php.js uses JsLint to help us keep our code consistent and prevent some common bugs.

Eventually we want all code to pass or at least take into consideration most fixes suggested by JsLint, following this JsLint configuration we’ve decided on.


Authors

Thanks to the following developers, you get to have parse_str goodness in JavaScript.

Comments

Add Comment
Use:
[CODE]
your_stuff('here');
[/CODE]
for proper code formatting
By submitting code here you are allowing us to use it in php.js hence dual licensing it under the MIT and GPL licenses

Gravatar
Brett Zamir
Aug 16th Permalink

q  @Dreamer: Fixed in Git. Thanks for the report!

Gravatar
Dreamer
Aug 15th Permalink

q  Bug report --- "TypeError: str.replace is not a function" (Copied from FireBug)

// PHPJS cannot parse the following codes, while it's possible in PHP
parse_str('&first=foo');
parse_str('first=foo&');
parse_str('&first=foo&');

Gravatar
Kevin van Zonneveld
Jun 19th Permalink

q  @ droope: Although there are plenty open jslint issues with this function, i is actually defined and in my tests it works. What platform are you experiencing issues on?

Gravatar
droope
May 15th Permalink

q  Hi.

I keep getting "i is not defined". Perhaps something broke?

Regards,
Droope

Gravatar
Brett Zamir
3 May '09 Permalink

q  Thanks much, stag019... Fixed in SVN (including moving equality operators to identity ones)...

Gravatar
stag019
2 May '09 Permalink

q  Two things I forgot to mention:
Depends on urldecode now.
Some places I use '==' or '!=' where I could probably use '===' or '!=='. These should probably be fixed.

Gravatar
stag019
2 May '09 Permalink

q  Well, time to bugfix myself. ;P

Looking through the PHP source I realized I completely neglected to test anything with a null character in it. Aparently PHP completely ignores everything after a null character in the key name, but leaves it alone in the value.

Change the function fixStr to

return urldecode(str).replace(/([\"'])/g, '\\$1').replace(/\n/g, '\\n').replace(/\r/g, '\\r');



Underneath

		while(key.charAt(0) === ' ')
		{
			key = key.substr(1);
		}

add

		if(key.indexOf('\0') !== -1)
		{
			key = key.substr(0, key.indexOf('\0'));
		}

Gravatar
Brett Zamir
30 Apr '09 Permalink

q  Looks good, stag019, thanks! Added in SVN. (Netbeans just caught the fact that "chr" needed to be declared too.). If you like, you might also consider voting for https://bugzilla.mozilla.org/show_bug.cgi?id=488227 as this is one behavior JS can't emulate from many PHP functions (in this case, we'd get a way to use parse_str() to put variables into a local scope only without using an array).

Gravatar
stag019
30 Apr '09 Permalink

q  Oops, I also forgot to mention that the second parameter is now optional, as it uses the window variable if none is defined.

Gravatar
stag019
30 Apr '09 Permalink

q  Sure, it parses strings such as array[key]=value into an array, in the same fashion PHP does. It also handles the encoding of the period and space characters, in the same fashion that PHP does.

Gravatar
Kevin van Zonneveld
29 Apr '09 Permalink

q  stag019: Sorry but there are a lot function we need to maintain. Would it be possible for you to explain how your implementation beats our current one?

Gravatar
stag019
27 Apr '09 Permalink

q  I couldn't think of a way to do it without eval(), but it better emulates PHP.

function parse_str(str, array)
{
	var glue1 = '=', glue2 = '&', array2 = String(str).split(glue2),
	i, j, tmp, key, value, bracket, keys, evalStr,
	fixStr = function(str)
	{
		return urldecode(str).replace(/([\"'])/g, '\\$1').replace(/\0/g, '\\0').replace(/\n/g, '\\n').replace(/\r/g, '\\r');
	};

	if(!array)
	{
		array = window;
	}

	for(i = 0; i < array2.length; i++)
	{
		tmp = array2[i].split(glue1);
		if(tmp.length < 2)
		{
			tmp = [tmp, ''];
		}
		key   = fixStr(tmp[0]);
		value = fixStr(tmp[1]);
		while(key.charAt(0) == ' ')
		{
			key = key.substr(1);
		}
		if(key && key.charAt(0) != '[')
		{
			keys    = [];
			bracket = 0;
			for(j = 0; j < key.length; j++)
			{
				if(key.charAt(j) == '[' && !bracket)
				{
					bracket = j + 1;
				}
				else if(key.charAt(j) == ']')
				{
					if(bracket)
					{
						if(!keys.length)
						{
							keys.push(key.substr(0, bracket - 1));
						}
						keys.push(key.substr(bracket, j - bracket));
						bracket = 0;
						if(key.charAt(j + 1) !== '[')
						{
							break;
						}
					}
				}
			}
			if(!keys.length)
			{
				keys = [key];
			}
			for(j = 0; j < keys[0].length; j++)
			{
				chr = keys[0].charAt(j);
				if(chr == ' ' || chr == '.' || chr == '[')
				{
					keys[0] = keys[0].substr(0, j) + '_' + keys[0].substr(j + 1);
				}
				if(chr == '[')
				{
					break;
				}
			}
			evalStr = 'array';
			for(j = 0; j < keys.length; j++)
			{
				key = keys[j];
				if((key !== '' && key !== ' ') || j === 0)
				{
					key = "'" + key + "'";
				}
				else
				{
					key = eval(evalStr + '.push([]);') - 1;
				}
				evalStr += '[' + key + ']';
				if(j != keys.length - 1 && eval('typeof ' + evalStr) == 'undefined')
				{
					eval(evalStr + ' = [];');
				}
			}
			evalStr += " = '" + value + "';\n";
			eval(evalStr);
		}
	}
}

Gravatar
Kevin van Zonneveld
3 Mar '08 Permalink

q  @ Michael White: great! thank you!

Gravatar
Michael White
2 Mar '08 Permalink

q  This function did not take into account the fact that the URL string might be encoded so I modified it to handle encoded URLs and added a new example.


[CODE=&quot;JavaScript&quot;]
function parse_str(str, array){
// http://kevin.vanzonneveld.net
// + original by: Cagri Ekin
// * example 1: parse_str('first=foo&amp;second=bar');
// * returns 1: { first: 'foo', second: 'bar' }
// * example 2: parse_str('str_a=Jack+and+Jill+didn%27t+see+the+well.');
// * returns 2: { str_a: &quot;Jack and Jill didn't see the well.&quot; }

var glue1 = '=';
var glue2 = '&amp;';

var array2 = str.split(glue2);
var array3 = [];
for(var x=0; x&lt;array2.length; x++){
var tmp = array2[x].split(glue1);
array3[unescape(tmp[0])] = unescape(tmp[1]).replace(/[+]/g, ' '); // This is the modified line.
}

if(array){
array = array3;
} else {
return array3;
}
}
[/CODE]

http://crestidg.com


Contribute a New function