定制 codememory/entity-response-control 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

codememory/entity-response-control

Composer 安装命令:

composer require codememory/entity-response-control

包简介

Controls the response from entities or other objects based on constraints

README 文档

README

This library is designed for prototyping the returned array, basically you describe the schema of how and what you want to get in the array. As an example: You have a Doctrine entity and you need to give data to this entity in the API. To do this, you can create a prototype in the form of a class, which will then be converted into an array. You may ask how this is different from symfony/serializer, but the difference is that this library actively uses PHP attributes and you can format your data however you want. In addition, this library can easily handle the task when you need to give in one query not only all entities but also other data of each object, which were received by another SQL/DQL query. Below are some examples

Translated with DeepL.com (free version)

Install

$ composer require codememory/entity-response-control

Manager creation

use Codememory\EntityResponseControl\ResponsePrototypeManager;
use Codememory\Reflection\ReflectorManager;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Codememory\EntityResponseControl\Factory\PrototypeExecutionContextFactory;
use Codememory\EntityResponseControl\Factory\PropertyWrapperFactory;
use Codememory\EntityResponseControl\Factory\PropertyExecutionContextFactory;
use Codememory\EntityResponseControl\Collectors\BaseCollector;
use Codememory\EntityResponseControl\DecoratorRegistrar;
use Codememory\EntityResponseControl\NamingStrategy\SnakeCamelNamingStrategy;

$cache = new FilesystemAdapter('codememory', directory: 'cache');
$reflectorManager = new ReflectorManager($cache);
$decoratorRegistrar = new DecoratorRegistrar();

$manager = new ResponsePrototypeManager(
    $reflectorManager,
    new PrototypeExecutionContextFactory(
        new PropertyWrapperFactory()
    ),
    new PropertyExecutionContextFactory(),
    new BaseCollector(
        $decoratorRegistrar,
        new SnakeCamelNamingStrategy()
    ),
    $decoratorRegistrar
);

A simple Example

// Entity
class User {
    .... 
    
    public function getName(): string
    {
        return 'Foo';
    }
    
    public function getSurname(): string
    {
        return 'Bar';
    }
}

// Prototype
class UserPrototype {
    private ?string $name = null; // null - Default value
    private ?string $surname = null; // null - Default value
}

// In order to collect it is necessary to call the collect method
$result = $manager->collect(UserPrototype::class, new User());

[!] Note that if you pass collect as an array of objects as the second argument, the array will be multidimensional, otherwise you will get just an associative array

Use of decorators

// Entity
use Codememory\EntityResponseControl\Decorators\Property;

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

class User {   
    public function getOrders(): array
    {
        return [
            new Order('Order 1'),
            new Order('Order 2'),
            new Order('Order 3')
        ];
    }
    
    public function getSurname(): string
    {
        return 'Bar';
    }
}

// Prototype
class OrderPrototype {
    private ?string $name = null;
}

class UserPrototype {
    #[Property\Getter(['getOrders'])] // Explicitly specify the method to use, since we don't have a getCountOrders or isCountOrders method
    #[Property\Length]
    private ?int $countOrders = null;
    
    #[Property\Nested(OrderPrototype::class)]
    private array $orders = [];
    private ?string $surname = null;
}

$result = $manager->collect(UserPrototype::class, new User());

result1

Let's imagine that we have users, and statistics on users is considered in a separate query and we need to somehow combine all this data in one query

use Codememory\EntityResponseControl\Decorators\Property;

class User {
    public function __construct(
        private string $id,
        private string $name
    ) {}
    
    public function getId(): string
    {
        return $this->id;
    }
    
    public function getName(): string
    {
        return $this->name;
    }
}

$users = [
    new User('1', 'User 1'),
    new User('2', 'User 2'),
    new User('3', 'User 3')
];

$metadata = [
    'success_orders' => [
        '1' => 10,
        '2' => 20,
        '3' => 30
    ]
];

class UserPrototype {
    private ?string $id = null;
    
    // As the first argument it is necessary to pass the name of the getter, in our case the unique value of the user is his identifier
    // The second argument is to pass the key from where to take values from metadata
    #[Property\FromObjectMetadata('getId', 'success_orders')]
    private ?int $countSuccessOrders = null;
}

$result = $manager->collect(UserPrototype::class, $users, metadata: $metadata);

result2

You can also pass metadata not directly to the manager, but also use decorators, for example, to pull data using the service

use Codememory\EntityResponseControl\Decorators\Property;
use Codememory\EntityResponseControl\Decorators\Prototype;
use Codememory\EntityResponseControl\Interfaces\PrototypeExecutionContextInterface;

class User {
    public function __construct(
        private string $id,
        private string $name
    ) {}
    
    public function getId(): string
    {
        return $this->id;
    }
    
    public function getName(): string
    {
        return $this->name;
    }
}

class Service {
    public static function getMetadata(PrototypeExecutionContextInterface $executionContext): void
    {
        $executionContext->setMetadata([
            'success_orders' => [
                '1' => 10,
                '2' => 20,
                '3' => 30
            ]
        ]);
    }
}

$users = [
    new User('1', 'User 1'),
    new User('2', 'User 2'),
    new User('3', 'User 3')
];

#[Prototype\Callback([Service::class, 'getMetadata'])]
class UserPrototype {
    private ?string $id = null;

    #[Property\FromObjectMetadata('getId', 'success_orders')]
    private ?int $countSuccessOrders = null;
}

// The result will be the same as in the last example.
$result = $manager->collect(UserPrototype::class, $users);

codememory/entity-response-control 适用场景与选型建议

codememory/entity-response-control 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 90 次下载、GitHub Stars 达 1, 最近一次更新时间为 2023 年 02 月 03 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 codememory/entity-response-control 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 codememory/entity-response-control 我们能提供哪些服务?
定制开发 / 二次开发

基于 codememory/entity-response-control 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 90
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 17
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2023-02-03