Last active
May 23, 2019 16:59
-
-
Save cfg/968825f82192eec92f33 to your computer and use it in GitHub Desktop.
Modified version of parse_str() from phpjs - http://phpjs.org/functions/parse_str/ - Source: https://github.com/kvz/phpjs/blob/master/functions/strings/parse_str.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function parse_str(str, array) { | |
// discuss at: http://phpjs.org/functions/parse_str/ | |
// original by: Cagri Ekin | |
// improved by: Michael White (http://getsprink.com) | |
// improved by: Jack | |
// improved by: Brett Zamir (http://brett-zamir.me) | |
// bugfixed by: Onno Marsman | |
// bugfixed by: Brett Zamir (http://brett-zamir.me) | |
// bugfixed by: stag019 | |
// bugfixed by: Brett Zamir (http://brett-zamir.me) | |
// bugfixed by: MIO_KODUKI (http://mio-koduki.blogspot.com/) | |
// reimplemented by: stag019 | |
// input by: Dreamer | |
// input by: Zaide (http://zaidesthings.com/) | |
// input by: David Pesta (http://davidpesta.com/) | |
// input by: jeicquest | |
// modified by: 2015-04-13 corey gilmore | |
// - indent using tabs (personal preference) | |
// - always return a parsed object, never put variables in the global scope | |
// - strip leading ? and & from the passed string | |
// -------------------------------------------------- | |
// note: When a particular argument has been passed, and the returned value is different parse_str of PHP. For example, a=b=c&d====c | |
// test: skip | |
// example 1: var arr = {}; | |
// example 1: parse_str('first=foo&second=bar', arr); | |
// example 1: $result = arr | |
// returns 1: { first: 'foo', second: 'bar' } | |
// example 2: var arr = {}; | |
// example 2: parse_str('str_a=Jack+and+Jill+didn%27t+see+the+well.', arr); | |
// example 2: $result = arr | |
// returns 2: { str_a: "Jack and Jill didn't see the well." } | |
// example 3: var abc = {3:'a'}; | |
// example 3: parse_str('abc[a][b]["c"]=def&abc[q]=t+5'); | |
// returns 3: {"3":"a","a":{"b":{"c":"def"}},"q":"t 5"} | |
var strArr = String(str) | |
.replace(/^[?&]/, '') | |
.replace(/&$/, '') | |
.split('&'), | |
sal = strArr.length, | |
i, j, ct, p, lastObj, obj, lastIter, undef, chr, tmp, key, value, | |
postLeftBracketPos, keys, keysLen, | |
fixStr = function (str) { | |
return decodeURIComponent(str.replace(/\+/g, '%20')); | |
}; | |
if (!array) { | |
array = {}; | |
} | |
for (i = 0; i < sal; i++) { | |
tmp = strArr[i].split('='); | |
key = fixStr(tmp[0]); | |
value = (tmp.length < 2) ? '' : fixStr(tmp[1]); | |
while (key.charAt(0) === ' ') { | |
key = key.slice(1); | |
} | |
if (key.indexOf('\x00') > -1) { | |
key = key.slice(0, key.indexOf('\x00')); | |
} | |
if (key && key.charAt(0) !== '[') { | |
keys = []; | |
postLeftBracketPos = 0; | |
for (j = 0; j < key.length; j++) { | |
if (key.charAt(j) === '[' && !postLeftBracketPos) { | |
postLeftBracketPos = j + 1; | |
} else if (key.charAt(j) === ']') { | |
if (postLeftBracketPos) { | |
if (!keys.length) { | |
keys.push(key.slice(0, postLeftBracketPos - 1)); | |
} | |
keys.push(key.substr(postLeftBracketPos, j - postLeftBracketPos)); | |
postLeftBracketPos = 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; | |
} | |
} | |
obj = array; | |
for (j = 0, keysLen = keys.length; j < keysLen; j++) { | |
key = keys[j].replace(/^['"]/, '') | |
.replace(/['"]$/, ''); | |
lastIter = j !== keys.length - 1; | |
lastObj = obj; | |
if ((key !== '' && key !== ' ') || j === 0) { | |
if (obj[key] === undef) { | |
obj[key] = {}; | |
} | |
obj = obj[key]; | |
} else { | |
// To insert new dimension | |
ct = -1; | |
for (p in obj) { | |
if (obj.hasOwnProperty(p)) { | |
if (+p > ct && p.match(/^\d+$/g)) { | |
ct = +p; | |
} | |
} | |
} | |
key = ct + 1; | |
} | |
} | |
lastObj[key] = value; | |
} | |
} | |
return array; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment