将多维对象转换为查询字符串

时间:2014-09-28 12:11:53

标签: javascript php

我有一个对象:

{"f":{"cid":"325","field_name[10][0]":"133","field_name[10][1]":"132","price":"320|3600"}}

我想将此对象转换为查询字符串。 我正在使用这个功能:

function toQueryString(obj, prefix) {
        var str = [];
        for(var p in obj) {
            var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
            str.push(typeof v == "object" ?
              toQueryString(v, k) :
              encodeURIComponent(k) + "=" + encodeURIComponent(v));
        }
        return str.join("&");
}

但是这个功能给了我结果:

f[cid]=325&f[field_name[10][0]]=133&f[field_name[10][1]]=132&f[price]=320%7C3600

这是错误的,因为我无法在服务器端获得正确的结果:

Array
(
    [f] => Array
        (
            [cid] => 325
            [field_name[10] => Array
                (
                    [0] => 133
                )

            [price] => 320|3600
        )
)

我该如何解决这个问题? 我认为正确的结果将是这样的:

f[cid]=325&f[field_name[[10][0]]]=133&f[field_name[[10][1]]]=132&f[price]=320%7C3600

5 个答案:

答案 0 :(得分:6)

为了纠正嵌套的查询字符串,我稍微改变了你的函数:

function toQueryString(obj, prefix) {
    var str = [], k, v;
    for(var p in obj) {
        if (!obj.hasOwnProperty(p)) {continue;} // skip things from the prototype
        if (~p.indexOf('[')) {
            k = prefix ? prefix + "[" + p.substring(0, p.indexOf('[')) + "]" + p.substring(p.indexOf('[')) : p;
// only put whatever is before the bracket into new brackets; append the rest
        } else {
            k = prefix ? prefix + "[" + p + "]" : p;
        }
        v = obj[p];
        str.push(typeof v == "object" ?
          toQueryString(v, k) :
          encodeURIComponent(k) + "=" + encodeURIComponent(v));
    }
    return str.join("&");
}

在原始对象上运行此函数现在为我们提供了此查询字符串:

f[cid]=325&f[field_name][10][0]=133&f[field_name][10][1]=132&f[price]=320|3600

如果我们将这个传递给告诉print_r($_GET)的PHP页面,它会给我们:

Array
(
    [f] => Array
        (
            [cid] => 325
            [field_name] => Array
                (
                    [10] => Array
                        (
                            [0] => 133
                            [1] => 132
                        )

                )

            [price] => 320|3600
        )

)

你想要什么,对吗?

答案 1 :(得分:0)

这个问题已经有了你想要的答案,但我决定解释我在评论中暗示的替代方案,因为我认为了解不止一种做事方式是好的。

它没有完全按照您的要求进行操作,但我认为这是一种更简单,更灵活,更易维护的传输任意对象的方法。

function toQueryString(obj, name)  {
    return encodeURIComponent(name) + '=' +
        encodeURIComponent(JSON.stringify(obj));
} 

在php方面(假设name"foo"),您所要做的就是:

$foo=json_decode($_GET["foo"], true);

唯一的困难是,如果您想支持某些版本的Internet Explorer,您必须使用JSON.stringify的polyfill,但这些都很容易获得。

缺点当然是一个额外的间接,但我认为有一个主要的好处:你正在将测试错误的负担推给浏览器制造商和(如果有必要)开发人员JSON.stringify你的任何实现决定使用。

当然,它具有引入新依赖关系的缺点,但我认为它足以保证它。

您的里程可能会有所不同。

另外:如果您可以使用POST请求发送数据,那么您可以直接将JSON.stringify的结果作为原始POST数据发送而不对其进行URL编码。在PHP方面,您可以使用json_decode(file_get_contents("php://input"), true)

获取它

答案 2 :(得分:0)

我刚刚写了这个。它对我有用。

let objToQueryString = function (obj, prefix) {
    let fields = [];
    if (obj && Object.keys(obj).length) {
        for (let i in obj) {
            if (obj.hasOwnProperty(i)) {
                if (typeof obj[i] === 'object') {
                    fields.push(objToQueryString(obj[i], prefix ? prefix + '[' + i + ']' : i));
                } else {
                    fields.push((prefix ? prefix + '[' + i + ']' : i) + '=' + (typeof obj[i] === 'undefined' ? '' : encodeURIComponent(obj[i])));
                }
            }
        }
    } else if (prefix) {
        fields.push(prefix + '=');
    }
    return fields.join('&');
};

objToQueryString({x: 1, y: 2, z: {a: 10, b: 20, c: {i: 100, j: null, k: {}}}}); //returns "x=1&y=2&z[a]=10&z[b]=20&z[c][i]=100&z[c][j]=&z[c][k]="

享受。

答案 3 :(得分:0)

TypeScript

auth-server-url

答案 4 :(得分:-2)

function solution(inputString, objectName)
{
    var startingIndex =  inputString.replace(/'/g, "").indexOf('{')
    var endingIndex =  inputString.replace(/'/g, "").indexOf('}')
    var propertyValuePairs = inputString.replace(/'/g, "").substring(startingIndex + 1, endingIndex ).split(',')
    var propertyValues = new Array();

    $.each(propertyValuePairs , function(index, element){ 
        var elements = element.split(':'); propertyValues.push({property: elements[0], value: elements[1]}); 
    });

    var result = "";

    for (var i = 0; i < propertyValues.length; i++) {
         result += objectName + "[" + propertyValues[i].property + "]" + "=" + propertyValues[i].value + "&";
    }
    return result.substring(0, result.length - 1);
}