blackprism/serializer

快速简单的 JSON 序列化库

1.2.0 2016-08-05 07:57 UTC

This package is not auto-updated.

Last update: 2024-09-14 18:42:17 UTC


README

序列化库 构建状态

适用于 PHP 7.0+ 的快速简单的 JSON 序列化库

序列化库被设计为非常快速且内存占用低。

如何使用它?

假设你有以下对象需要序列化/反序列化

class City
{
    private $name = '';
    private $country = null;

    public function setName(string $name)
    {
        $this->name = $name;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function countryIs(Country $country)
    {
        $this->country = $country;
    }

    public function getCountry()
    {
        return $this->country;
    }
}

class Country
{
    private $name = '';

    public function setName(string $name)
    {
        $this->name = $name;
    }

    public function getName(): string
    {
        return $this->name;
    }
}

首先,你需要设置配置,纯 PHP,无需 yml 或 xml。更快速、更轻量。

use Blackprism\Serializer\Configuration;
use Blackprism\Serializer\Value\ClassName;

$configuration = new Configuration();

$configurationObject = new Configuration\Object(new ClassName(City::class));
$configurationObject
    ->attributeUseMethod('name', 'setName', 'getName')
    ->attributeUseObject('country', new ClassName(Country::class), 'countryIs', 'getCountry')
    ->registerToConfiguration($configuration);

$configurationObject = new Configuration\Object(new ClassName(Country::class));
$configurationObject
    ->attributeUseMethod('name', 'setName', 'getName')
    ->registerToConfiguration($configuration);

现在,你可以序列化一个对象

use Blackprism\Serializer\Json;

$country = new Country();
$country->setName('France');

$city = new City();
$city->setName('Palaiseau');
$city->countryIs($country);

$jsonSerializer = new Json\Serialize($configuration);
$citySerialized = $jsonSerializer->serialize($city);

echo $citySerialized;

输出是

{
  "name": "Palaiseau",
  "country": {
    "name": "France"
  }
}

并且反序列化一个 JSON

use Blackprism\Serializer\Json;

$json = '{
          "name": "Palaiseau",
          "country": {
            "name": "France"
          }
        }';

$jsonDeserializer = new Json\Deserialize($configuration);
$city = $jsonDeserializer->deserialize($json, new ClassName(City::class));

print_r($city);

输出是

class City {
  private $name =>
    string(9) "Palaiseau"
  private $country =>
      class Country {
        private $name =>
        string(6) "France"
      }
}

自定义处理器

从上一个示例中,你只需稍微修改配置为以下内容

$configurationObject
    ->attributeUseMethod('name', 'setName', 'getName')
    ->attributeUseHandler(
		'country',
		new class implements Configuration\Type\HandlerDeserializerInterface {
            public function deserialize($object, $value)
            {
                $country = new Country();
                $country->setName($value['name']);
                $object->countryIs($country);
                $object->setName($object->getName() . ' (' . $country->getName() . ')');
            }
        },
        new class implements Configuration\Type\HandlerSerializerInterface {
            public function serialize($object)
            {
                $country = $object->getCountry();
                return ['name' => $country->getName() . '#' . spl_object_hash($country)];
            }
        }
	);

你有一个对象集合作为根节点吗?

假设你有一个这样的 JSON

[
    {
      "name": "Palaiseau",
      "country": {
        "name": "France"
      }
    },
    {
      "name": "Paris",
      "country": {
        "name": "France"
      }
    }
]

你需要使用 deserializeCollection

$cities = $jsonDeserializer->deserializeCollection($json, new ClassName(City::class));

你可以使用它来对 NoSQL 进行序列化/反序列化

使用 NoSQL 时,你经常在文档中添加一个属性来指定文档类型,例如

{
  "type": "city",
  "name": "Palaiseau"
}

标识文档的配置

use Blackprism\Serializer\Configuration;
use Blackprism\Serializer\Value\ClassName;

$configuration = new Configuration();
$configuration->identifierAttribute('type'); // name the property which contain the type of document

$configurationObject = new Configuration\Object(new ClassName(City::class));
$configurationObject
    ->attributeUseMethod('name', 'setName', 'getName')
    ->attributeUseIdentifiedObject('country', 'countryIs', 'getCountry') // You don't need to tell which class of object is
    ->registerToConfigurationWithIdentifier($configuration, 'city'); // Register the configuration with an identifier

$configurationObject = new Configuration\Object(new ClassName(Country::class));
$configurationObject
    ->attributeUseMethod('name', 'setName', 'getName')
    ->registerToConfigurationWithIdentifier($configuration, 'country'); // Register the configuration with an identifier

现在,你可以序列化为一个类型化的对象 JSON

use Blackprism\Serializer\Json;

$country = new Country();
$country->setName('France');

$city = new City();
$city->setName('Palaiseau');
$city->countryIs($country);

$jsonSerializer = new Json\Serialize($configuration);
$citySerialized = $jsonSerializer->serialize($city);

echo $citySerialized;

输出是

{
  "type": "city",
  "name": "Palaiseau",
  "country": {
    "type": "country",
    "name": "France"
  }
}

并且反序列化一个类型化的对象 JSON

use Blackprism\Serializer\Json;

$json = '{
          "type": "city",
          "name": "Palaiseau",
          "country": {
            "type": "country",
            "name": "France"
          }
        }';

$jsonDeserializer = new Json\Deserialize($configuration);
$city = $jsonDeserializer->deserialize($json);

print_r($city);

输出是

class City {
  private $name =>
    string(9) "Palaiseau"
  private $country =>
      class Country {
        private $name =>
        string(6) "France"
      }
}

注意:你有标识文档,所以即使根节点是集合,你也不需要使用 deserializeCollection。

基准测试

对于 100,000 次迭代

   JMS Serializer |      1.951 sec |          1537 KB |        1.829 sec |            1547 KB

Symfony Serializer | 0.210 秒 | 486 KB | 0.298 秒 | 488 KB Blackprism Serializer | 0.352 秒 | 464 KB | 0.311 秒 | 457 KB

测试协议可以在 序列化库基准测试 上找到

结论

如你所见,Blackprism 序列化库并不是最快的,但它有一个快速简单的配置,并且性能非常好,几乎与配置更复杂的 Symfony 序列化库相当。