indaxia/doctrine-orm-transformations

提供JSON准备好的Doctrine ORM实体-数组转换

2.0.1-stable 2016-11-18 04:44 UTC

README

功能

  • JSON-ready toArray 和 fromArray 特性(无需扩展类);
  • 使用策略逐个处理字段和嵌套子字段;
  • 支持所有Doctrine ORM列类型;
  • 支持JavaScript ISO8601格式的时间、日期和日期时间类型;
  • 支持嵌套实体和集合,适用于所有关联类型(注意自引用);
  • fromArray会请求EntityManager通过"referencedColumnName"查找或创建新的子实体(取决于标识符是否为空和策略);
  • 同样适用于集合成员(一对一、多对多);
  • 静态 toArrays 方法可以一次转换多个实体;
  • CVE-2015-0231Doctrine问题#4673提供解决方案;

第1步:安装

composer.json中添加

"require": {

    "Indaxia/doctrine-orm-transformations": "2.*"
}

然后

> cd <your doc root>
> composer update

需求与限制

第2步:引用公共类

use \Indaxia\OTR\ITransformable;
use \Indaxia\OTR\Traits\Transformable;
use \Indaxia\OTR\Annotations\Policy;

文档

完整文档

如何将实体转换为数组及其相反操作

假设我们有以下实体

    class Car implements ITransformable {
        use Transformable;
    
        /** @ORM\Id
         * @ORM\Column(type="integer") */
        protected $id;
        
        /** @Policy\To\Skip
         * @ORM\Column(type="string") */
        protected $keys;
        
        /** @ORM\OneToMany(targetEntity="Wheel") ... */
        protected $wheels;
        
        public function getId();
        public function getKeys() ...
        public function setKeys($v) ...
        ...
    }
    
    class Engine implements ITransformable {
        use Transformable;
        
        /** @ORM\Id
         * @ORM\Column(type="integer") */
        protected $id;
        
        /** @Policy\To\Skip
         * @ORM\Column(type="string") */
        protected $serialNumber;
        
        public function getId();
        public function getSerialNumber() ...
        public function setSerialNumber($v) ...
        ...
    }
    
    class Wheel implements ITransformable {
        use Transformable;
        
        /** @ORM\Id
         * @ORM\Column(type="integer") */
        protected $id;
        
        /** @Policy\Skip
         * @ORM\Column(type="string") */
        protected $brakes;
        
        /** @ORM\Column(type="string") */
        protected $model;
        
        public function getId();
        public function getBrakes() ...
        public function setBrakes($v) ...
        public function getModel() ...
        public function setModel($v) ...
        ...
    }

这里有一些$car。让我们将其转换为数组。

// Using global policy
$result = $car->toArray();
    
// Using local policy
$result = $car->toArray((new Policy\Auto)->inside([
    'wheels' => new Policy\To\FetchPaginate(['offset'=0, 'limit'=4, 'fromTail'=false])
]));

// Local policy overrides global policy
$result = $car->toArray((new Policy\Auto)->inside([
    'keys' => new Policy\Auto
]));

策略文档

$result将类似于以下内容

[
    '__meta' => ['class' => 'Car'],
    'id' => 1,
    'engine' => [
        '__meta' => ['class' => 'Engine', 'association' => 'OneToOne'],
        'id' => 83
    ],
    'wheels' => [
        '__meta' => ['class' => 'Wheel', 'association' => 'OneToMany'],
        'collection' => [
            [
                '_meta' => ['class' => 'Wheel'],
                'id' => 1,
                'model' => 'A'
            ],
            [
                '_meta' => ['class' => 'Wheel'],
                'id' => 2,
                'model' => 'A'
            ],
            [
                '_meta' => ['class' => 'Wheel'],
                'id' => 3,
                'model' => 'B'
            ],
            [
                '_meta' => ['class' => 'Wheel'],
                'id' => 4,
                'model' => 'B'
            ]
        ]
    ]
]

它已准备好进行JSON转换!

    echo json_encode($result);

您还可以使用array2XML等工具。

我们还可以将其转换回实体。它将通过EntityManager通过id检索子实体。不要忘记使用try-catch块以避免未捕获的异常。

$carB = new Car();
    
// Simple way
$carB->fromArray($result, $entityManager);

// With Policy
$carB->fromArray($result, $entityManager, (new Policy\Auto())->inside([
    'keys' => mew Policy\Skip,
    'engine' => (new Policy\Auto())->inside([
        'serialNumber' => new Policy\From\DenyNewUnset
    ]),
    'wheels' => (new Policy\Auto())->inside([
        'brakes' => new Policy\From\Auto
    ])
]);

策略文档

文档

完整文档

Indaxia / 2016