在Javascript中取消序列化PHP数组

在Javascript中取消序列化PHP数组,php,javascript,ajax,Php,Javascript,Ajax,我有一个表,其中包含大量的序列化数组行,我计划请求这些行并将其传递给JavaScript 问题是-是否可以使用JavaScript而不是PHP来取消序列化 否则,我将不得不加载所有行,循环它们并取消序列化,然后将它们分配到一个临时PHP数组,然后json_将其编码回JavaScript,如果我可以发送仍然序列化的数据,以便JavaScript可以在需要时取消序列化数据,这似乎是非常低效的 是否有一个内置的Javascript函数可以实现这一点,或者在编码之前我必须在PHP中循环行 注意我没有使用

我有一个表,其中包含大量的序列化数组行,我计划请求这些行并将其传递给
JavaScript

问题是-是否可以使用JavaScript而不是PHP来
取消序列化

否则,我将不得不加载所有行,循环它们并取消序列化,然后将它们分配到一个临时PHP数组,然后json_将其编码回JavaScript,如果我可以发送仍然序列化的数据,以便JavaScript可以在需要时取消序列化数据,这似乎是非常低效的

是否有一个内置的Javascript函数可以实现这一点,或者在编码之前我必须在PHP中循环行

注意我没有使用jQuery

编辑: 我的表中的PHP序列化数据示例:

a:8:{i:0;a:2:{i:0;i:10;i:1;i:11;}i:1;a:2:{i:0;i:9;i:1;i:11;}i:2;a:2:
{i:0;i:8;i:1;i:11;}i:3;a:2:{i:0;i:8;i:1;i:10;}i:4;a:2:{i:0;i:8;i:1;i:9;}i:5;a:2:
{i:0;i:8;i:1;i:8;}i:6;a:2:{i:0;i:8;i:1;i:7;}i:7;a:2:{i:0;i:8;i:1;i:6;}}

刚刚注意到您的评论,我们开始:

在PHP中

json_encode(unserialize(SerializedVal));
在JavaScript中:

JSON.parse(JsonString);

json_encode
环绕
unserialize

echo json_encode( unserialize( $array));

Php.js具有非序列化和序列化的javascript实现:


也就是说,在服务器端转换为JSON可能更有效。JSON.parse将比PHP.js的unserialize快得多。

我想我应该尝试编写一个js函数,可以对PHP序列化数据进行unserialize

但在使用此解决方案之前,请注意:

  • PHP的
    serialize
    函数生成的格式是特定于PHP的,因此最好的选择是使用PHP的
    unserialize
    ,以100%保证其工作正常
  • PHP可以将类信息存储在这些字符串中,甚至可以存储一些自定义序列化方法的输出。因此,要取消序列化这些字符串,您需要了解这些类和方法
  • PHP数据结构与JavaScript数据结构不一一对应:PHP关联数组可以将字符串作为键,因此它们看起来更像JavaScript对象而不是JS数组,但在PHP中,键保持插入顺序,键可以具有真正的数字数据类型,这在JS对象中是不可能的。有人可能会说,我们应该看看JS中的
    Map
    对象,但是这些对象允许将13和“13”作为单独的键存储,而PHP不允许这样做。我们现在只触及冰山一角
  • PHP序列化对象的受保护和私有属性,这不仅奇怪(这有多私有?),而且是JS中还不存在的概念,或者至少不以相同的方式存在。如果有人会在JS中实现(硬)私有属性,那么一些非序列化如何设置这样的私有属性呢
  • JSON是一种不特定于PHP的替代方法,也不关心自定义类。如果可以在序列化发生时访问的PHP源代码,那么将其更改为生成JSON。PHP为此提供了
    json\u encode
    ,JavaScript提供了
    json.parse
    对其进行解码。如果可以的话,这当然是一条路
如果您仍然认为需要JS unserialise函数,请继续阅读

下面是一个JS实现,它提供了一个
PHP
对象,其方法与内置的
JSON
对象类似:
parse
stringify

parse
方法的输入引用一个类时,它将首先检查您是否在(可选)第二个参数中传递了对该类的引用。否则,将为该类创建一个模拟(以避免意外的副作用)。无论哪种情况,都将创建该类的实例。如果输入字符串指定发生自定义序列化,则将调用该对象实例上的方法
unserialize
。您必须在该方法中提供逻辑,因为字符串本身并没有给出应该如何执行的信息。它仅在生成该字符串的PHP代码中已知

此实现还支持循环引用。当一个关联数组被证明是一个序列数组时,就会返回一个JS数组

constphp={
stdClass:function(){},
字符串化(val){
常量散列=新映射([[Infinity,”d:INF;“],[-Infinity,”d:-INF;“],[NaN,”d:NaN;“],[null,”N;“],[undefined,”N;“]);
const utf8length=str=>str?encodeURI(str).match(/(%)?./g).长度:0;
const serializeString=(s,delim=“”)=>“${utf8length(s)}:${delim[0]}${s}${delim[delim.length-1]}”;
设ref=0;
函数序列化(val,canReference=true){
if(hash.has(val))返回hash.get(val);
ref+=canReference;
if(typeof val==“string”)返回`s:${serializeString(val)};`;
if(typeof val==“number”)返回“${Math.round(val)==val?”i:“d”}:${(“+val.toUpperCase().replace(/(?\d)E/,“$1.0E”)};”;
if(typeof val==“boolean”)返回`b:${+val};`;
常量a=Array.isArray(val)| | val.constructor==Object;
set(val,`${“rR”[+a]}:${ref};`);
if(typeof val.serialize==“函数”){
返回`C:${serializeString(val.constructor.name)}:${serializeString(val.serialize(),“{}”)}`;
}
const vals=Object.entries(val.filter)([k,v])=>typeof v!=“函数”);
返回(a?“a”:`O:${serializeString(val.constructor.name)}`)
+`:${vals.length}:{${vals.map([k,v])=>serialize(a&&/^\d{1,16}$/.test(k)?+k:k,false)+serialize(v)).join(“”}}`;
}
返回序列化(val);
},
//在第二个参数中提供可以实例化的类
//例如{MyClass1,MyClass2}
解析(str,allowedClasses={}){
allowedClasses.stdClass=PHP.stdClass;//始终允许。
设偏移量=0;
常量值=[null];
const specialNums={“INF”:无限,“-INF”:-Infinity,“NAN”:NAN};
常量kick=(msg,i=offset)=>{抛出新错误