Skip to main content

Crate phpserz

Crate phpserz 

Source
Expand description

§PHPserz

A Rust crate for parsing and deserializing the PHP serialization format1.

§Features

  • Support for PHP objects with public, protected, and private members
  • Fast. Exceeding 1 GiB/s in application benchmarks
  • Zero allocation and zero copy parsing

§Quick start

To start, below is an example of generating PHP serialized output

<?php
class Example {
    public $name = "John Doe";
    private $age = 42;
    protected $isActive = true;
    public $scores = [95.5, 88.0, 92.3];
    public $metadata = [
        "id" => 12345,
        "tags" => ["php", "rust", "serialization"]
    ];
}

$example = new Example();
$serialized = serialize($example);
echo $serialized;

The output will be:

O:7:"Example":5:{s:4:"name";s:8:"John Doe";s:12:"\0Example\0age";i:42;s:11:"\0*\0isActive";b:1;s:6:"scores";a:3:{i:0;d:95.5;i:1;d:88.0;i:2;d:92.3;}s:8:"metadata";a:2:{s:2:"id";i:12345;s:4:"tags";a:3:{i:0;s:3:"php";i:1;s:4:"rust";i:2;s:13:"serialization";}}}

§Deserialization

PHPserz supports ergonomic serde deserialization:

#[cfg(feature = "serde")] {
use phpserz::PhpDeserializer;
use serde::Deserialize;
use std::collections::BTreeMap;

#[derive(Debug, Deserialize, PartialEq)]
struct Example {
    name: String,
    age: i32,
    #[serde(rename = "isActive")]
    is_active: bool,
    scores: BTreeMap<u32, f64>,
    metadata: Metadata,
}

#[derive(Debug, Deserialize, PartialEq)]
struct Metadata {
    id: i32,
    tags: BTreeMap<u32, String>,
}

let serialized = b"O:7:\"Example\":5:{s:4:\"name\";s:8:\"John Doe\";s:12:\"\0Example\0age\";i:42;s:11:\"\0*\0isActive\";b:1;s:6:\"scores\";a:3:{i:0;d:95.5;i:1;d:88.0;i:2;d:92.3;}s:8:\"metadata\";a:2:{s:2:\"id\";i:12345;s:4:\"tags\";a:3:{i:0;s:3:\"php\";i:1;s:4:\"rust\";i:2;s:13:\"serialization\";}}}";

let mut deserializer = PhpDeserializer::new(serialized);
let example = Example::deserialize(&mut deserializer).unwrap();

assert_eq!(
    example,
    Example {
        name: "John Doe".to_string(),
        age: 42,
        is_active: true,
        scores: BTreeMap::from([
            (0, 95.5),
            (1, 88.0),
            (2, 92.3),
        ]),
        metadata: Metadata {
            id: 12345,
            tags: BTreeMap::from([
                (0, "php".to_string()),
                (1, "rust".to_string()),
                (2, "serialization".to_string())
            ]),
        }
    }
);
}

§Token Parsing

One can go one level lower and drive the parser manually to better inspect the data.

use phpserz::{Error, PhpParser, PhpToken, PhpBstr, PhpVisibility};

let serialized = b"O:7:\"Example\":5:{s:4:\"name\";s:8:\"John Doe\";s:12:\"\0Example\0age\";i:42;s:11:\"\0*\0isActive\";b:1;s:6:\"scores\";a:3:{i:0;d:95.5;i:1;d:88.0;i:2;d:92.3;}s:8:\"metadata\";a:2:{s:2:\"id\";i:12345;s:4:\"tags\";a:3:{i:0;s:3:\"php\";i:1;s:4:\"rust\";i:2;s:13:\"serialization\";}}}";

let mut parser = PhpParser::new(&serialized[..]);

assert_eq!(
    parser.read_token().unwrap(),
    PhpToken::Object {
        class: PhpBstr::new(b"Example"),
        properties: 5
    }
);

let PhpToken::String(prop) = parser.read_token().unwrap() else {
    panic!("Expected a string token");
};

assert_eq!(prop, PhpBstr::new(b"name"));
let prop = prop.to_property();
assert_eq!(prop.to_str().unwrap(), "name");
assert_eq!(prop.visibility(), PhpVisibility::Public);

// ...

Structs§

Error
An PHPserz error.
PhpBstr
A byte string that is conventionally UTF-8.
PhpDeserializer
A deserializer for PHP serialized data.
PhpParser
A parser for the PHP serialized format.
PhpProperty
A PHP object property with its name and visibility.

Enums§

ErrorKind
The kind of error that can occur when working with PHP serialized data.
PhpReferenceKind
The kind of PHP reference token.
PhpToken
A token in the PHP serialized format.
PhpTokenKind
The kind of token without data.
PhpVisibility
The visibility of a property in a PHP object.