that's almost good
to translate php array to js you have two solutions :
if it is a key => value array, it translate to an object
$data = ['username' => "myUsername", 'password' => "myPassword"];
becomes
let data = {'username': "myUsername", 'password': "myPassword"};
the ; is optionnal and quotes ",' works as in php AFAIK
while PHP arrays without key translate to js array
$data = ["myUsername", "myPassword"];
becomes
let data = ["myUsername", "myPassword"]
these are similar
a way to know how to translate structure is to json_encode them in php, as JSON is a subset of js (not perfectly but these are edge case AFAIK), you can use the given JSON as your variable declaration in js
// PHP :
// json_encode(['username' => "myUsername", 'password' => "myPassword"]);
// returns {"username":"myUsername","password":"myPassword"}
let myObject = {"username":"myUsername","password":"myPassword"}
console.log(myObject)
// same with non keyed array
// json_encode(["myUsername", "myPassword"]);
// returns ["myUsername","myPassword"]
let myArray = ["myUsername","myPassword"]
console.log(myArray)
here's a tentative to create serialize in javascript
Makopa gave this node package which do the serialization in comments use it if you can as it will work better than this little script I made
Warning it won't work exactly like serialize because :
I can't find how to serialize callback functions because I couldn't get it to work so if someone has a working exemple I'm happy to add it
JavaScript doesn't know anything about private/protected attribute in objects
JavaScript doesn't make difference between int and double/float
Any other situation I may have forgotten to test and thus didn't implement
If any of you find an error don't hesitate to tell me in comment
let serialize = value => {
let serializeNull = value => {
return `N;`
}
let serializeBool = value => {
return `b:${value?1:0};`
}
let serializeInt = value => {
return `i:${parseInt(value)};`
}
let serializeDouble = value => {
return `d:${value};`
}
let serializeString = value => {
return `s:${value.length}:"${value}";`
}
let serializeArray = value => {
let serialized = `a:${value.length}:{`
value.forEach((val, i) => {
serialized += serialize(i)
if(val === value) {
throw new Error("sorry doesn't support array referencing themselves")
} else {
serialized += serialize(val)
}
})
return serialized + "}"
}
let serializeKeyedArray = value => {
let entries = Object.entries(value)
let serialized = `a:${entries.length}:{`
entries.forEach(entry => {
serialized += serialize(entry[0])
if(entry[1] === value) {
throw new Error("sorry doesn't support array referencing themselves")
} else {
serialized += serialize(entry[1])
}
})
return serialized + "}"
}
let serializeObject = value => {
let entries = Object.entries(value)
let serialized = `O:${value.constructor.name.length}:"${value.constructor.name}":${entries.length}:{`
entries.forEach(([key, val]) => {
serialized += serialize(key)
// if protected key should become \0*\0${key}
// if private key should become \0${value.constructor.name}\0${key}
if(val === value) {
serialized += "r:1;"
} else {
serialized += serialize(val)
}
})
return serialized + "}"
}
switch(typeof value) {
case "number": // int or double
if (""+value == parseInt(""+value)) { return serializeInt(value) }
else { return serializeDouble(value) }
break
case "boolean": // boolean
return serializeBool(value)
break
case "string": // string
return serializeString(value)
break
case "undefined": // undefined
return serializeNull(value)
break
case "object": // Array, primitive object, object from class or null
if (Array.isArray(value)) { return serializeArray(value) }
else if (value === null) { return serializeNull(value) }
else if (value.constructor.name !== "Object") { return serializeObject(value) }
else { return serializeKeyedArray(value) }
break
default: throw new Error("sorry I don't know how to serialize this")
}
}
class TestClass {
constructor() {
this.self = this
this.a = 42
this.b = "How are you ?"
}
}
let tests = [
{expected: `i:1;`, val: 1},
{expected: `i:-1;`, val: -1},
{expected: `d:1;`, val: 1.0},
{expected: `d:1.5;`, val: 1.5},
{expected: `d:-4.2;`, val: -4.2},
{expected: `b:1;`, val: true},
{expected: `b:0;`, val: false},
{expected: `N;`, val: null},
{expected: `N;`, val: undefined},
{expected: `s:4:"test";`, val: "test"},
{expected: `s:5:"hello";`, val: "hello"},
{expected: `a:3:{i:0;i:1;i:1;s:2:"hi";i:2;i:5;}`, val: [1, "hi", 5]},
{expected: `a:3:{s:1:"a";i:1;s:1:"b";s:2:"hi";s:1:"c";i:5;}`, val: {a:1, b:"hi", c:5}},
{expected: `O:9:"TestClass":3:{s:4:"self";r:1;s:1:"a";i:42;s:1:"b";s:13:"How are you ?";}`, val: new TestClass()}
]
tests.forEach(val => {
let serialized = serialize(val.val)
let log = `expected : '${val.expected}', got : '${serialized}', value : ${(()=>{
if(typeof val.val === "object") {
return val.val ? Object.entries(val.val).join(", ") : val.val // null
} else {
return val.val ? val.val.toString() : val.val // undefined
}
})()}`
if(val.expected === serialized) {
console.log(log)
} else {
console.error(log)
}
})
There are still errors as you can see :
- the
double having no usefull digit after the dot (like 1.0000) are considered int because in JS they are both the same Number
return values are based on the return of serialize on this site running php 7.3.5 on the 7th and 8th of august 2019
let data = {'username': "myUsername", 'password': "myPassword"};using brackets[], creates an array in javascript; using braces{}, creates an object.JSON.stringifyin javascript is a lot different fromserializein PHP. You could compare the outputs. However, if this is just for data transfer, then this will do just fine.serialize