同福

使用Java实现PHP的序列化和反序列化函数serialize和unserialize的功能【20210507】

介绍

介绍

福哥最近在把一部分功能从PHP转入Java里面,在处理PHP的序列化(Serialize)数据的时候遇到了问题,经过一番折腾找到了一个在Java里实现序列化的功能的第三方库。

现在,福哥将这个库的使用方法交给大家!!

依赖

首先导入phprpc的依赖库

<dependency>
    <groupId>org.sction</groupId>
    <artifactId>phprpc</artifactId>
    <version>3.0.2</version>
</dependency>

使用

使用PHPSerializer反序列化经过PHP序列化过的字符串需要知道目标字符串里存的是什么类型的数据,不同的数据类型是需要使用不同的实体对象去接收反射数据的。

单字符串类型

原数据就是一个字符串

try {
    PHPSerializer ps = new PHPSerializer();
    String s;

    s = (String) ps.unserialize(new String("s:12:\"福哥真好\";").getBytes(), String.class);

    return s;
}
catch (Exception e){
    e.printStackTrace();
}

27a2367f2072c43b.jpg

单整型类型

原数据就是一个整型数字

try {
    PHPSerializer ps = new PHPSerializer();
    Integer s;

    s = (Integer) ps.unserialize(new String("i:518168;").getBytes(), Integer.class);

    return s;
}
catch (Exception e){
    e.printStackTrace();
}

单双精类型

原数据就是一个小数

try {
    PHPSerializer ps = new PHPSerializer();
    Double s;

    s = (Double) ps.unserialize(new String("d:518168.99;").getBytes(), Double.class);

    return s;
}
catch (Exception e){
    e.printStackTrace();
}

NULL类型

原数据就是一个null,由于没有类型,反序列化会失败

try {
    PHPSerializer ps = new PHPSerializer();
    String s;

    s = (String) ps.unserialize(new String("N;").getBytes(), String.class);

    return s;
}
catch (Exception e){
    e.printStackTrace();
}

实体对象类型

如果原数据是一个对象(就是数组的下标为字符串的情况),那么就可以建立同样结构的实体对象,使用这个实体对象可以直接接收数组数据

注意:实体对象必须是public的

实体对象

@Data
public class MyUser {
    Integer id;
    String name;
    String note;
}

反序列化

try {
    PHPSerializer ps = new PHPSerializer();
    MyUser s;

    s = (MyUser) ps.unserialize(new String("a:3:{s:2:\"id\";i:35;s:4:\"name\";s:15:\"鬼谷子叔叔\";s:4:\"note\";s:1:\"s\";}").getBytes(), MyUser.class);

    return s;
}
catch (Exception e){
    e.printStackTrace();
}

87876c0c51d4f086.jpg

数组类型

如果原数据是一个数组(就是数组下标为数字的情况)的话,那么可以使用AssocArray类型将结果集先收集起来,然后再使用Cast对象将数据转换成Java对应的类型

注意:实体对象必须是public的

实体对象

@Data
public class MyTag {
    Integer id;
    String tag;
}

反序列化

try {
    PHPSerializer ps = new PHPSerializer();
    List<MyTag> s = new ArrayList<>();
    AssocArray aa;

    aa = (AssocArray) ps.unserialize(new String("a:3:{i:0;a:2:{s:2:\"id\";i:15;s:3:\"tag\";s:5:\"C/C++\";}i:1;a:2:{s:2:\"id\";i:16;s:3:\"tag\";s:4:\"Java\";}i:2;a:2:{s:2:\"id\";i:18;s:3:\"tag\";s:3:\"PHP\";}}").getBytes());
    for(int i=0;i<aa.size();i++){
        s.add((MyTag) Cast.cast(aa.get(i), MyTag.class));
    }

    return s;
}
catch (Exception e){
    e.printStackTrace();
}

6593fe3911722ab2.jpg

总结

可以看到PHPSerializer基本可以满足我们在Java反序列化使用PHP语言序列化的数据结构的需要了。