tatter/roster 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

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

tatter/roster

Composer 安装命令:

composer require tatter/roster

包简介

Bulk name lookup for database relations in CodeIgniter 4

README 文档

README

Bulk name lookup for database relations in CodeIgniter 4

Coverage Status

Quick Start

  1. Install with Composer: > composer require tatter/roster
  2. Create a Roster class
  3. Load high-performance names: <?= service('roster')->user(1) ?>

Description

Roster solves a common, niche problem in an elegant way: quick access to display names for entity relations without requiring database lookup. An example... Your e-commerce app allows users to list their own products along with their username. To display the full product page, traditionally you would either need a database JOIN to fetch the usernames along with each product, or rely on a third-party solution like Object Relation Mapping (ORM) to load the related information. Roster simplifies and optimizes this by preloading batches of object names and caching them for convenient on-the-fly access.

Installation

Install easily via Composer to take advantage of CodeIgniter 4's autoloading capabilities and always be up-to-date:

  • > composer require tatter/roster

Or, install manually by downloading the source files and adding the directory to app/Config/Autoload.php.

Usage

The Roster service handles locating and interacting with your Roster classes, so all you need to do is create some Rosters. All Rosters must meet a few criteria to be discovered:

  • Rosters must extend the Base Roster (Tatter\Roster\BaseRoster)
  • Rosters must be located in a Rosters folder within a namespace (e.g. App\Rosters)
  • Rosters must be named by their lookup followed "Roster" (e.g. "CarRoster")

BaseRoster

BaseRoster defines the three methods that your class must implement:

  • protected function key(): string;
  • protected function fetchAll(): array;
  • protected function fetch($id): ?string;

See the BaseRoster file for more details.

ModelRoster

Most of the time Rosters will be fetching information from the database. In order to make this more convenient and reduce repetitive code this library comes with an intermediate support class, ModelRoster. If your Roster aligns with an existing Model then simply extend the ModelRoster class and supply these required fields:

  • protected $modelName;
  • protected $field;

Displaying

Once your Rosters are configured, use the service with the Roster name as the method and the ID of the item as the sole parameter:

$userName = service('roster')->user($userId);

Example

You are developing a blog. At the bottom of every post is a comments section where logged in users may post replies. Being the bright developer you are, you decide to use Tatter\Roster to handle the display and save on expensive database joins for every page.

First let's handle displaying the username next to each commet. You already have UserModel so we can use the ModelRoster to make it easier. Create app/Rosters/UserRoster.php:

namespace App\Rosters;

use App\Models\UserModel;
use Tatter\Roster\ModelRoster;

class UserRoster extends ModelRoster
{
	protected $modelName = UserModel::class;
	protected $field     = 'username';
}

That's it! ModelRoster handles retrieving the values based those properties. Now in our comment HTML block we can use the Roster service to display each username:

<?php foreach ($comments as $comment): ?>
<div class="comment">
    <blockquote><?= $comment->content ?></blockquote>
    <div class="comment-footer">
        Commented by <?= service('roster')->user($comment->user_id) ?>
    </div>
</div>
<?php endforeach; ?>

Let's do our blog tags next: under the post title we want to display each tag for this post. Unfortunately tags are in the format "[General] Specific" so no single field will work for the display. We can still use the ModelRoster but instead specifying the field we will provide our own determining method. Create app/Rosters/TagRoster.php:

namespace App\Rosters;

use App\Models\TagModel;
use Tatter\Roster\ModelRoster;

class TagRoster extends ModelRoster
{
    protected $modelName = TagModel::class;

    protected function getFieldValue(array $row): string
    {
        // Convert the database row from TagModel into its displayable form
        $general  = $row['general'];
        $specific = $row['specific'];

        return "[$general] $specific";
    }
}

Now our blog post header looks much cleaner:

<h1><?= $post->title ?></h1>
<div class="tags">
    <?php foreach ($post->tags as $tagId): ?>
    <span class="tag"><?= service('roster')->tag($tagId) ?></span>
    <?php endforeach; ?>
</div>

Finally, our blog is going to display a sidebar menu with post-relevant links to partners. This data will come from a third-party API, which would be an expensive call to make on every page load so we create a Roster for it. Because the data source is not a Model we need to make our own extension of the Base Roster. Create app/Rosters/LinkRoster.php:

namespace App\Rosters;

use App\Libraries\LinkApi;
use Tatter\Roster\BaseRoster;

class LinkRoster extends BaseRoster
{
    /**
     * Returns the handler-specific identifier used for caching
     */
    protected function key(): string
    {
        return 'roster-links';
    }

    /**
     * Loads all IDs and their names from the data source.
     */
    protected function fetchAll(): array
    {
        $results = [];
        $links   = new LinkApi();

        foreach ($links->list() as $link) {
            $results[$link->uid] = $link->href;
        }

        return $results;
    }

    /**
     * Loads a single ID and name from the data source.
     */
    protected function fetch($id): ?string
    {
        $links = new LinkApi();

        if ($link = $links->get($id)) {
            return $link->href;
        }

        return null;
    }
}

A little bit more code, but using BaseRoster gives a lot more control about where the data comes from and how it is formatted. You've probably already figure this part out, but let's finish off our links with their HTML menu:

<nav class="links-menu">
    <h3>Visit our partner blogs!</h3>
    <ul>
        <?php foreach ($post->partnerLinks as $uid): ?>
        <span class="tag"><?= service('roster')->link($uid) ?></span>
        <?php endforeach; ?>
    </ul>
</nav>

tatter/roster 适用场景与选型建议

tatter/roster 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 3.78k 次下载、GitHub Stars 达 6, 最近一次更新时间为 2021 年 09 月 28 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「database」 「performance」 「codeigniter」 「relations」 「roster」 「codeigniter4」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

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

围绕 tatter/roster 我们能提供哪些服务?
定制开发 / 二次开发

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

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

GitHub 信息

  • Stars: 6
  • Watchers: 2
  • Forks: 2
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2021-09-28