【问题标题】:how to translate PHP code with serialization into a javascript code?如何将带有序列化的 PHP 代码翻译成 javascript 代码?
【发布时间】:2019-08-07 14:29:09
【问题描述】:

我得到了这行 PHP 代码,但我不知道如何准确地用 Javascript 翻译它。

PHP 代码:

$data = ['username' => "myUsername", 'password' => "myPassword"];
serialize($data);

这是准确翻译的 javascript 代码吗? JS代码:

let data = [{'username': "myUsername"}, {'password': "myPassword"}];
JSON.stringify(data);

原始代码在 PHP 中。所以我需要修改node.js中的javascript

【问题讨论】:

  • 我相信你想要这个:let data = {'username': "myUsername", 'password': "myPassword"}; 使用方括号 [],在 javascript 中创建一个数组;使用大括号{},创建一个对象。
  • javascript 中的 JSON.stringify 与 PHP 中的 serialize 有很大不同。您可以比较输出。但是,如果这只是用于数据传输,那么就可以了。
  • “会有问题吗?” - 取决于您之后实际想要对结果做什么......如果您发送给谁/无论您期望有什么解密后再次以 PHP 序列化格式的数据,然后发送一些其他格式(例如 JSON)可能不会解决问题。
  • @Makopa JavaScript 中没有与serialize类似的东西
  • 这就是我提到它的原因,因为您接受的答案对您所说的问题没有任何帮助

标签: javascript php node.js


【解决方案1】:

差不多好了

要将 php 数组转换为 js,您有两种解决方案:

如果是key => value 数组,则转换为对象

$data = ['username' => "myUsername", 'password' => "myPassword"];

变成

let data = {'username': "myUsername", 'password': "myPassword"};

; 是可选的,引号 ",' 在 php AFAIK 中的工作原理

PHP 没有键的数组转换为 js 数组

$data = ["myUsername", "myPassword"];

变成

let data = ["myUsername", "myPassword"]

这些是相似的


了解如何翻译结构的一种方法是将 json_encode 它们转换为 php,因为 JSONjs 的子集(不完美,但这些是边缘情况 AFAIK),您可以使用给定的 JSON作为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)

这是一个尝试在 javascript 中创建serialize

Makopa 给了 this node package which do the serialization 在 cmets 中使用它,因为它会比我制作的这个小脚本更好用

警告它不会像序列化一样工作,因为:

  • 我找不到如何序列化回调函数,因为我无法让它工作,所以如果有人有一个工作示例,我很乐意添加它

  • JavaScript 对对象中的私有/受保护属性一无所知

  • JavaScript 在 int 和 double/float 之间没有区别

  • 我可能忘记测试并因此未实施的任何其他情况

  • 如果有任何人发现错误,请随时在评论中告诉我

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)
  }
})

如您所见,仍有错误:

  • 点后没有有用数字的double(如1.0000)被认为是int,因为在JS中它们都是相同的Number

返回值基于 serialize 在 2019 年 8 月 7 日和 8 日运行 php 7.3.5this site 上的返回

【讨论】:

  • 除此之外忽略了 serialize() 的使用,没有等效的 javascript
  • 是的......本来不想提这个,但是......“IDK序列化”并不真正属于以serialize()作为主要部分的问题的答案
  • 感谢大家的关心。我想我只是使用 node 包来处理 node.js 中的序列化
  • @Makopa 这是新代码,还是重新开发现有 API
  • @RiggsFolly 嗨!好。我的客户服务是 PHP 代码。所以他们向我发送如何加密请求正文然后将其发送到他们的 PHP 服务。他们发给我的算法是 PHP 代码。但是我的 API 是从 node.js 构建的。所以我要用javascript编写算法,然后将响应发送到他们的PHP服务进行解密。
猜你喜欢
  • 1970-01-01
  • 2018-09-09
  • 2020-12-01
  • 2017-07-24
  • 1970-01-01
  • 2021-10-19
  • 1970-01-01
  • 1970-01-01
  • 2019-06-14
相关资源
最近更新 更多