psx/data

数据处理库,用于读取和写入不同格式的POPOs

v6.0.4 2024-09-15 16:31 UTC

README

数据处理库,有助于在不同格式的POPOs之间读写数据。

使用方法

以下示例展示了如何读取/写入复杂模型。

// create processor
$processor = new Processor(Configuration::createDefault());

// example json data which we want to parse in our model
$in = <<<JSON
{
    "id": 1,
    "title": "Lorem ipsum",
    "author": {
        "id": 1,
        "name": "Foo",
        "email": "foo@bar.com",
    },
    "comments": [{
        "id": 1,
        "author": {
            "id": 1,
            "name": "Foo",
            "email": "foo@bar.com",
        },
        "text": "Lorem ipsum"
    },{
        "id": 2,
        "author": {
            "id": 1,
            "name": "Foo",
            "email": "foo@bar.com",
        },
        "text": "Lorem ipsum"
    }],
    "date": "2016-03-28T22:40:00Z"
}
JSON;

// reads the json data into a custom model class
$model = $processor->read(News::class, Payload::json($in));

// the model can be used to get or set data
$model->getAuthor()->getName();
$model->getComments()[0]->getText();

// writes the model back to json
$out = $processor->write(Payload::json($model));

// model classes
class News
{
    private ?int $id = null;
    private ?string $title = null;
    protected ?Author $author = null;
    /**
     * @var array<Comment>|null
     */
    private ?array $comments = null;
     #[Format('date-time')]
    private ?string $date;

    // getter/setter implementations removed for readability
}

class Author
{
    private ?int $id = null;
    private ?string $name = null;
    private ?string $email = null;

    // getter/setter implementations removed for readability
}

class Comment
{
    private ?int $id = null;
    private ?Author $author = null;
    private ?string $text = null;

    // getter/setter implementations removed for readability
}

格式

该库支持不同的读取器和写入器类以生成不同的数据格式。如果您想读取特定格式,可以提供数据的内容类型。例如,如果您想读取XML,可以使用以下负载

$payload = Payload::create($in, 'application/xml');

处理器使用读取器工厂来获取适用于特定内容类型的适当读取器。在这种情况下,它将使用XML读取器。读取器工厂可以很容易地通过不同的读取器类扩展来支持其他数据格式。

$configuration->getReaderFactory()->addReader(new Acme\Reader(), 32);

要从传入的HTTP请求中生成负载,您只需将正文设置为数据,并将内容类型从标题中设置。您如何访问此数据取决于HTTP接口。对于PSR-7请求,您可以使用

$payload = Payload::create(
    (string) $request->getBody(),
    $request->getHeaderLine('Content-Type')
);

另一方面,如果您想将数据作为响应写入,则使用

$payload = Payload::create(
    $model,
    $request->getHeaderLine('Accept')
);

写入器工厂也可以通过自定义写入器实现进行扩展。

$configuration->getWriterFactory()->addWriter(new Acme\Writer(), 64);

约束

还可以向模型类添加特定约束。以下是一些示例

#[Required(['title'])]
class News
{
    #[Pattern('[A-z]')]
    private ?string $title = null;

     #[MinLength(3)]
     #[MaxLength(255)]
    private ?string $text = null;

    #[Enum(['active', 'deleted'])]
    private ?string $status = null;

    #[Minimum(0)]
    #[Maximum(5)]
    private ?int $rating = null;
}

所有可用属性均位于 psx/schema 项目中。

转换

每个读取器类返回一种可以轻松处理的数据形式。例如,json读取器返回由json_decode生成的stdClass,xml读取器返回DOMDocument。为了统一输出,我们使用转换类,这些类接收读取器的输出并返回标准化格式。例如,对于xml内容,我们默认应用XmlArray转换器,该转换器将转换DOMDocument。因此,您可以直接使用读取器的输出。

如果您想根据XSD模式验证传入的XML数据,则可以使用XmlValidator转换器

$payload = Payload::xml($data);
$payload->setTransformer(new XmlValidator('path/to/schema.xsd'));

$model = $processor->read(News::class, $payload);

导出器

如果您写入数据,则可以将任意对象设置为负载。我们使用导出器类来返回该对象的实际数据表示形式。默认情况下,导出器还读取psx/schema属性,因此您可以使用相同的模型进行传入和传出数据。但是,也可以使用不同的类。例如,您可以使用仅用于传入数据的psx/schema属性创建模型类,而对于传出数据,如果您已经具有具有这些注解的对象,则可以使用JMS导出器。

如果您有其他方法可以提取对象的数据(例如,toArray方法,它返回对象的可用字段),则可以轻松编写自定义导出器。