承接 demos-europe/edt-paths 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

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

demos-europe/edt-paths

Composer 安装命令:

composer require demos-europe/edt-paths

包简介

Tools to create paths between entities and entity properties.

README 文档

README

Tools to create paths between entities and entity properties.

Provides PHP classes to enable you to use phpdoc tags to annotate classes as path segment and reference other path segments to define a directed graph, which can be used to build property paths for conditions and sort methods with IDE support.

Overview

This component enables you to mark classes as path segment and reference such classes in other classes as relationships.

To give an example suppose we have a class Comment with a relationship to the class Article which in turn has a relationship to the class Author. If we want to build a path using the property names of the relationships we could define an array like the following manually: ['article', 'author']. For this you not only have to know the property names at the time you write the path but also need to adjust all paths using a property when the name of the property changes.

An alternative would be to define string constants in each class with the names of each property. In this case you could do something like this [Comment::ARTICLE, Article::AUTHOR]. This way you can change the value of the constant without adjusting each path manually. Also, your IDE can help you find each usage of a property in your application.

This component extends on these advantages and uses phpdoc @property-read tags instead of constants. As a result you can define the path with the following expression: $comment→article→author→getAsNames(). The result will be the same as in the examples above. This way your IDE provides you with a list of available relationships at each segment and can keep track of the usage of each @property-read, allowing for easy property renaming.

To enable a class as path segment and add working @property-read tags you only need to add the PropertyAutoPathTrait as use inside your class. After that you can add @property-read tags with the type of the target class as shown below for the Article class.

/**
 * @property-read Author $author
 * @property-read Comment $comments
 */
class Article
{
    use \EDT\PathBuilding\PropertyAutoPathTrait;

    private $text;

    public function __construct(string $text)
    {
        $this->text = $text;
    }

    public function getText(): string
    {
        return $this->text;
    }
}

By default, the constructor of your class will be ignored and a not fully initialized instance will be returned. This means that you may not be able to use the instances resulting from a path for anything else but further path building. So the above class will work for $comment→article→authors→getAsNames() but will fail for $comment→article→getText().

However, if you pass a factory callback to the trait the path segments will be created using that callback, resulting in fully usable instances of your class. Such factory will depend on your system architecture. The following example can only give a rough idea, your solution may differ.

/**
 * @property-read Author $author
 * @property-read Comment $comments
 */
class Article
{
    use \EDT\PathBuilding\PropertyAutoPathTrait;

    private $text;

    public function __construct(string $text, ArticleRepository $articleRepository)
    {
        $this->childCreateCallback =
        static function (string $class, $parent, string $parentPropertyName) use ($articleRepository) {
            if ($parent instanceof Comment) {
                $articleId = $parent->getArticleId();
                $article = $articleRepository->getArticle($articleId);
                $article->setParent($parent);
                $article->setParentPropertyName($parentPropertyName);
                return $article;
            }
            if ($parent instanceof Author) {
                return $this->createChild($class, $parent, $parentPropertyName);
            }
            // ... more class checks
        };
        $this->text = $text;
    }

    public function getText(): string
    {
        return $this->text;
    }
}

Note that this example will fall back to the not fully initialized instances in case of to-many relationships. This is the case because it would otherwise need to select an Article instance in case of paths like $author→articles. Such paths can still be used for further path building like $author→articles→comments→getAsNames(). But like mentioned before it may fail if methods of the actual class are used, like in the following access: $author→articles→getText(). This is a known limitation considered acceptable, as the main usage is the building of paths, not a replacement of getters to fetch actual instances.

Supported tags

The example above uses the property-read tag to add properties to your path class. This is the default as it seems to make the most sense for the path building use case, however you can change it to other tags if desired as shown below.

/**
 * @property Author $author
 * @property Comment $comments
 */
class Article
{
    use \EDT\PathBuilding\PropertyAutoPathTrait;

    protected function getDocblockTraitEvaluator(): DocblockPropertyByTraitEvaluator
    {
        if (null === $this->docblockTraitEvaluator) {
            $this->docblockTraitEvaluator = PropertyEvaluatorPool::getInstance()->getEvaluator(PropertyAutoPathTrait::class, ['property']); // replaces the default 'property-read'
        }

        return $this->docblockTraitEvaluator;
    }
}

You can set multiple tags too, as is shown below for the property-read and property tags.

/**
 * @property Author $author
 * @property Comment $comments
 */
class Article
{
    use \EDT\PathBuilding\PropertyAutoPathTrait;

    protected function getDocblockTraitEvaluator(): DocblockPropertyByTraitEvaluator
    {
        if (null === $this->docblockTraitEvaluator) {
            $this->docblockTraitEvaluator = PropertyEvaluatorPool::getInstance()->getEvaluator(PropertyAutoPathTrait::class, ['property-read', 'property']);
        }

        return $this->docblockTraitEvaluator;
    }
}

Supported tags are:

  • property

  • property-read

  • property-write

  • param

  • var

Credits and acknowledgements

Conception and implementation by Christian Dressler with many thanks to eFrane.

demos-europe/edt-paths 适用场景与选型建议

demos-europe/edt-paths 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 26.31k 次下载、GitHub Stars 达 2, 最近一次更新时间为 2022 年 06 月 23 日, 在 PHP 生态内属于活跃度较高的组件。

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

围绕 demos-europe/edt-paths 我们能提供哪些服务?
定制开发 / 二次开发

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

  • 总下载量: 26.31k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 2
  • 点击次数: 33
  • 依赖项目数: 2
  • 推荐数: 0

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2022-06-23