0

I am trying to unserialize the following string:

a:1:{i:0;a:9:{s:12:"model_number";s:8:"TTN037-7";s:5:"price";s:4:"2935";s:10:"unit_price";d:2405.32000000000016370904631912708282470703125;s:8:"id_price";d:2935;s:9:"sales_tax";d:223.68000000000000682121026329696178436279296875;s:5:"sales";d:2380.32000000000016370904631912708282470703125;s:7:"service";s:2:"25";s:7:"freight";s:3:"306";s:13:"comm_category";s:3:"X24";}}

Using the following js code:

function unserialize(data) {
    // http://kevin.vanzonneveld.net
    // +     original by: Arpad Ray (mailto:[email protected])
    // +     improved by: Pedro Tainha (http://www.pedrotainha.com)
    // +     bugfixed by: dptr1988
    // +      revised by: d3x
    // +     improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +        input by: Brett Zamir (http://brett-zamir.me)
    // +     improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +     improved by: Chris
    // +     improved by: James
    // +        input by: Martin (http://www.erlenwiese.de/)
    // +     bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +     improved by: Le Torbi
    // +     input by: kilops
    // +     bugfixed by: Brett Zamir (http://brett-zamir.me)
    // +      input by: Jaroslaw Czarniak
    // %            note: We feel the main purpose of this function should be to ease the transport of data between php & js
    // %            note: Aiming for PHP-compatibility, we have to translate objects to arrays
    // *       example 1: unserialize('a:3:{i:0;s:5:"Kevin";i:1;s:3:"van";i:2;s:9:"Zonneveld";}');
    // *       returns 1: ['Kevin', 'van', 'Zonneveld']
    // *       example 2: unserialize('a:3:{s:9:"firstName";s:5:"Kevin";s:7:"midName";s:3:"van";s:7:"surName";s:9:"Zonneveld";}');
    // *       returns 2: {firstName: 'Kevin', midName: 'van', surName: 'Zonneveld'}
    var that = this,
    utf8Overhead = function (chr) {
        // http://phpjs.org/functions/unserialize:571#comment_95906
        var code = chr.charCodeAt(0);
        if (code < 0x0080) {
            return 0;
        }
        if (code < 0x0800) {
            return 1;
        }
        return 2;
    },
    error = function (type, msg, filename, line) {
        throw new that.window[type](msg, filename, line);
    },
    read_until = function (data, offset, stopchr) {
        var i = 2, buf = [], chr = data.slice(offset, offset + 1);

        while (chr != stopchr) {
            if ((i + offset) > data.length) {
                error('Error', 'Invalid');
            }
            buf.push(chr);
            chr = data.slice(offset + (i - 1), offset + i);
            i += 1;
        }
        return [buf.length, buf.join('')];
    },
    read_chrs = function (data, offset, length) {
        var i, chr, buf;

        buf = [];
        for (i = 0; i < length; i++) {
            chr = data.slice(offset + (i - 1), offset + i);
            buf.push(chr);
            length -= utf8Overhead(chr);
        }
        return [buf.length, buf.join('')];
    },
    _unserialize = function (data, offset) {
        var dtype, dataoffset, keyandchrs, keys,
            readdata, readData, ccount, stringlength,
            i, key, kprops, kchrs, vprops, vchrs, value,
            chrs = 0,
            typeconvert = function (x) {
                return x;
            };

        if (!offset) {
            offset = 0;
        }
        dtype = (data.slice(offset, offset + 1)).toLowerCase();

        dataoffset = offset + 2;

        switch (dtype) {
            case 'i':
                typeconvert = function (x) {
                    return parseInt(x, 10);
                };
                readData = read_until(data, dataoffset, ';');
                chrs = readData[0];
                readdata = readData[1];
                dataoffset += chrs + 1;
                break;
            case 'b':
                typeconvert = function (x) {
                    return parseInt(x, 10) !== 0;
                };
                readData = read_until(data, dataoffset, ';');
                chrs = readData[0];
                readdata = readData[1];
                dataoffset += chrs + 1;
                break;
            case 'd':
                typeconvert = function (x) {
                    return parseFloat(x);
                };
                readData = read_until(data, dataoffset, ';');
                chrs = readData[0];
                readdata = readData[1];
                dataoffset += chrs + 1;
                break;
            case 'n':
                readdata = null;
                break;
            case 's':
                ccount = read_until(data, dataoffset, ':');
                chrs = ccount[0];
                stringlength = ccount[1];
                dataoffset += chrs + 2;

                readData = read_chrs(data, dataoffset + 1, parseInt(stringlength, 10));
                chrs = readData[0];
                readdata = readData[1];
                dataoffset += chrs + 2;
                if (chrs != parseInt(stringlength, 10) && chrs != readdata.length) {
                    error('SyntaxError', 'String length mismatch');
                }
                break;
            case 'a':
                readdata = {};

                keyandchrs = read_until(data, dataoffset, ':');
                chrs = keyandchrs[0];
                keys = keyandchrs[1];
                dataoffset += chrs + 2;

                for (i = 0; i < parseInt(keys, 10); i++) {
                    kprops = _unserialize(data, dataoffset);
                    kchrs = kprops[1];
                    key = kprops[2];
                    dataoffset += kchrs;

                    vprops = _unserialize(data, dataoffset);
                    vchrs = vprops[1];
                    value = vprops[2];
                    dataoffset += vchrs;

                    readdata[key] = value;
                }

                dataoffset += 1;
                break;
            default:
                error('SyntaxError', 'Unknown / Unhandled data type(s): ' + dtype);
                break;
        }
        return [dtype, dataoffset - offset, typeconvert(readdata)];
    }
;
    return _unserialize((data + ''), 0)[2];
}

function utf8_decode(str_data) {
    // http://kevin.vanzonneveld.net
    // +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
    // +      input by: Aman Gupta
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Norman "zEh" Fuchs
    // +   bugfixed by: hitwork
    // +   bugfixed by: Onno Marsman
    // +      input by: Brett Zamir (http://brett-zamir.me)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // *     example 1: utf8_decode('Kevin van Zonneveld');
    // *     returns 1: 'Kevin van Zonneveld'
    var tmp_arr = [],
    i = 0,
    ac = 0,
    c1 = 0,
    c2 = 0,
    c3 = 0;

    str_data += '';

    while (i < str_data.length) {
        c1 = str_data.charCodeAt(i);
        if (c1 < 128) {
            tmp_arr[ac++] = String.fromCharCode(c1);
            i++;
        } else if (c1 > 191 && c1 < 224) {
            c2 = str_data.charCodeAt(i + 1);
            tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
            i += 2;
        } else {
            c2 = str_data.charCodeAt(i + 1);
            c3 = str_data.charCodeAt(i + 2);
            tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
            i += 3;
        }
    }

    return tmp_arr.join('');
}

But i am unable to get any values back when doing this:

function testPHP() {
    var ret;

    ret = unserialize('a:1:{i:0;a:9:{s:12:"model_number";s:8:"TTN037-7";s:5:"price";s:4:"2935";s:10:"unit_price";d:2405.32000000000016370904631912708282470703125;s:8:"id_price";d:2935;s:9:"sales_tax";d:223.68000000000000682121026329696178436279296875;s:5:"sales";d:2380.32000000000016370904631912708282470703125;s:7:"service";s:2:"25";s:7:"freight";s:3:"306";s:13:"comm_category";s:3:"X24";}}');
    alert(ret[0]);
    alert(ret[1]);
    alert(ret[2]);
    alert(ret[3]);
}

I have set up a jsfiddle for you all to test > http://jsfiddle.net/XRrFS/2/

What would i be missing?

7
  • 3
    The first question that comes to my mind is: Where are you getting this string from in the first place? Do you really need to deserialize PHP array serialisations or could you exchange the data in a different format, say, JSON? Apart from that, the function seems to be working correctly. As far as I can tell, the array consists of one associative array, which in JavaScript is represented as object. So the result is an array with an object as first element, and that's what you have... nothing wrong with your code. Commented Aug 14, 2012 at 13:11
  • Have no control over how it stores the string into the database. I need to decode it in order to place it onto a ASP.net web page. Commented Aug 14, 2012 at 13:13
  • See, array with one element: codepad.org/ZZsA2EZV. That's why alert(ret[0]) shows [object Object] and the others undefined. You just have to access re[0] properly. If you don't know how to work with arrays and objects, I recommend to read the MDN JavaScript Guide. Commented Aug 14, 2012 at 13:17
  • Oh! just read your above comment right now. Sorry, I thought you're using PHP. Commented Aug 14, 2012 at 13:17
  • @FelixKling: How would i get the data then if its all inside ret[0]? Commented Aug 14, 2012 at 13:21

1 Answer 1

1

It works just fine. Replace the alerts with console.log(ret) and log at the output. It looks like this:

Object
  0: Object
    comm_category: "X24"
    freight: "306"
    id_price: 2935
    model_number: "TTN037-7"
    price: "2935"
    sales: 2380.32
    sales_tax: 223.68
    service: "25"
    unit_price: 2405.32

http://jsfiddle.net/TrHpc/

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.