tobento/service-repository 问题修复 & 功能扩展

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

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

tobento/service-repository

最新稳定版本:2.0.3

Composer 安装命令:

composer require tobento/service-repository

包简介

Repository interfaces for PHP applications.

README 文档

README

Repository interfaces for PHP applications.

Table of Contents

Getting started

Add the latest version of the repository service project running this command.

composer require tobento/service-repository

Requirements

  • PHP 8.4 or greater

Highlights

  • Framework-agnostic, will work with any project
  • Decoupled design

Documentation

Interfaces

Repository Interface

namespace Tobento\Service\Repository;

interface RepositoryInterface extends ReadRepositoryInterface, WriteRepositoryInterface
{
    //
}

Read Repository Interface

namespace Tobento\Service\Repository;

interface ReadRepositoryInterface
{
    /**
     * Returns the found entity using the specified id (primary key)
     * or null if none found.
     *
     * @param int|string $id
     * @return null|object
     * @throws RepositoryReadException
     */
    public function findById(int|string $id): null|object;
    
    /**
     * Returns the found entity using the specified id (primary key)
     * or null if none found.
     *
     * @param int|string ...$ids
     * @return iterable<object>
     * @throws RepositoryReadException
     */
    public function findByIds(int|string ...$ids): iterable;

    /**
     * Returns the found entity using the specified where parameters
     * or null if none found.
     *
     * @param array $where
     * @return null|object
     * @throws RepositoryReadException
     */
    public function findOne(array $where = []): null|object;

    /**
     * Returns the found entities using the specified parameters.
     *
     * @param array $where Usually where parameters.
     * @param array $orderBy The order by parameters.
     * @param null|int|array $limit The limit e.g. 5 or [5(number), 10(offset)].
     * @return iterable<object>
     * @throws RepositoryReadException
     */
    public function findAll(array $where = [], array $orderBy = [], null|int|array $limit = null): iterable;
    
    /**
     * Returns the found column values using the specified parameters.
     *
     * @param string $column The column name for the values.
     * @param null|string $key The column name for the index key.
     * @param array $where Usually where parameters.
     * @param array $orderBy The order by parameters.
     * @param null|int|array $limit The limit e.g. 5 or [5(number), 10(offset)].
     * @return array
     * @throws RepositoryReadException
     */
    public function findColumn(
        string $column,
        null|string $key = null,
        array $where = [],
        array $orderBy = [],
        null|int|array $limit = null
    ): array;
    
    /**
     * Returns the number of items using the specified where parameters.
     *
     * @param array $where
     * @return int
     * @throws RepositoryReadException
     */
    public function count(array $where = []): int;
}

Write Repository Interface

namespace Tobento\Service\Repository;

interface WriteRepositoryInterface
{
    /**
     * Create an entity.
     *
     * @param array $attributes
     * @return object The created entity.
     * @throws RepositoryCreateException
     */
    public function create(array $attributes): object;
    
    /**
     * Update an entity by id.
     *
     * @param string|int $id
     * @param array $attributes The attributes to update the entity.
     * @return object The updated entity.
     * @throws RepositoryUpdateException
     */
    public function updateById(string|int $id, array $attributes): object;
    
    /**
     * Update entities.
     *
     * @param array $where The where parameters.
     * @param array $attributes The attributes to update the entities.
     * @return iterable<object> The updated entities.
     * @throws RepositoryUpdateException
     */
    public function update(array $where, array $attributes): iterable;
    
    /**
     * Delete an entity by id.
     *
     * @param string|int $id
     * @return object The deleted entity.
     * @throws RepositoryDeleteException
     */
    public function deleteById(string|int $id): object;
    
    /**
     * Delete entities.
     *
     * @param array $where The where parameters.
     * @return iterable<object> The deleted entities.
     * @throws RepositoryDeleteException
     */
    public function delete(array $where): iterable;
}

Locales Aware Interface

You may implement the locales aware interface into your repository using the HasLocales trait.

use Tobento\Service\Repository\HasLocales;
use Tobento\Service\Repository\LocalesAware;
use Tobento\Service\Repository\RepositoryInterface;

class SomeRepository implements RepositoryInterface, LocalesAware
{
    use HasLocales;
    
    // ...
}
namespace Tobento\Service\Repository;

interface LocalesAware
{
    /**
     * Sets the locale.
     *
     * @param string $locale
     * @return static $this
     */
    public function locale(string $locale): static;
    
    /**
     * Sets the locale returing a new instance.
     *
     * @param string $locale
     * @return static
     */
    public function withLocale(string $locale): static;
    
    /**
     * Returns the locale.
     *
     * @return string
     */
    public function getLocale(): string;
    
    /**
     * Sets the locales.
     *
     * @param string ...$locales
     * @return static $this
     */
    public function locales(string ...$locales): static;
    
    /**
     * Sets the locales returning a new instance.
     *
     * @param string ...$locales
     * @return static
     */
    public function withLocales(string ...$locales): static;
    
    /**
     * Returns the locales.
     *
     * @return array
     */
    public function getLocales(): array;
    
    /**
     * Sets the locale fallbacks.
     *
     * @param array<string, string> $localeFallbacks
     * @return static $this
     */
    public function localeFallbacks(array $localeFallbacks): static;
    
    /**
     * Sets the locale fallbacks returning a new instance.
     *
     * @param array<string, string> $localeFallbacks
     * @return static
     */
    public function withLocaleFallbacks(array $localeFallbacks): static;
    
    /**
     * Returns the locale fallbacks.
     *
     * @return array<string, string>
     */
    public function getLocaleFallbacks(): array;
}

Entity Factory Interface

namespace Tobento\Service\Repository;

interface EntityFactoryInterface
{
    /**
     * Create an entity from array.
     *
     * @param array $attributes
     * @return object The created entity.
     */
    public function createEntityFromArray(array $attributes): object;
}

Null Repository

The NullRepository is a no-operation implementation of RepositoryInterface.
It accepts all read and write operations without performing any side effects and returns neutral, predictable values.

This makes it useful for:

  • disabling persistence in development or testing environments
  • providing a safe fallback when no repository is configured
  • stubbing repository dependencies in prototypes
  • avoiding conditional logic (if ($repo) { ... })
  • ensuring repository calls never throw or mutate state

Features

  • Implements the full RepositoryInterface
  • All read operations return neutral values:
    • null for single-entity lookups
    • empty arrays/iterables for multi-entity queries
    • 0 for counts
  • All write operations return simple objects based on the provided attributes
  • No exceptions are thrown
  • No state is stored and no side effects occur

Returned Values Overview

Method Return Value
findById() null
findByIds() []
findOne() null
findAll() []
findColumn() []
count() 0
create() (object)$attributes
updateById() (object)$attributes
update() []
deleteById() (object)['id' => $id]
delete() []

Example

use Tobento\Service\Repository\NullRepository;

$repo = new NullRepository();

// Always returns null
$user = $repo->findById(1);

// Always returns empty iterable
$users = $repo->findAll(['active' => true]);

// Creates a simple object from attributes
$entity = $repo->create(['name' => 'Alice']);
// $entity->name === 'Alice'

// Update returns an object with the provided attributes
$updated = $repo->updateById(5, ['name' => 'Bob']);

// Delete returns an object containing the id
$deleted = $repo->deleteById(10);
// $deleted->id === 10

Read Only Repository Adapter

Any repository implementing the RepositoryInterface::class can be made read-only by decorating them using the ReadOnlyRepositoryAdapter::class:

use Tobento\Service\Repository\ReadOnlyRepositoryAdapter;
use Tobento\Service\Repository\RepositoryInterface;

$readOnlyRepository = new ReadOnlyRepositoryAdapter(
    repository: $repository, // RepositoryInterface
);

Events Repository Adapter

Any repository implementing the ReadRepositoryInterface::class or WriteRepositoryInterface::class can be made to dispatch default events by decorating them using the EventsRepositoryAdapter::class:

use Psr\EventDispatcher\EventDispatcherInterface;
use Tobento\Service\Repository\EventsRepositoryAdapter;
use Tobento\Service\Repository\ReadRepositoryInterface;
use Tobento\Service\Repository\WriteRepositoryInterface;
use Tobento\Service\Repository\Event;

$eventsRepository = new EventsRepositoryAdapter(
    eventDispatcher: $eventDispatcher, // EventDispatcherInterface
    repository: $repository, // ReadRepositoryInterface or WriteRepositoryInterface
    
    // if false (default) event attributes get used on write methods
    immutableAttributes: false,
);

Default Events

Event Description
Event\Retrieved::class The event will dispatch after an entity is retrieved from the read methods only.
Event\Creating::class The event will dispatch before an entity is created.
Event\Created::class The event will dispatch after an entity is created.
Event\Updating::class The event will dispatch before an entity is updated.
Event\Updated::class The event will dispatch after an entity is updated.
Event\Deleting::class The event will dispatch before an entity is deleted.
Event\Deleted::class The event will dispatch after an entity is deleted.

Eventer

The eventer may be used to easily create a EventsRepositoryAdapter::class if you want only to have certain events dispatched.

Create Eventer

use Psr\EventDispatcher\EventDispatcherInterface;
use Tobento\Service\Repository\EventerInterface;
use Tobento\Service\Repository\Eventer;

$eventer = new Eventer(
    eventDispatcher: $eventDispatcher, // EventDispatcherInterface
);

var_dump($eventer instanceof EventerInterface);
// bool(true)

Using Eventer

use Tobento\Service\Repository\EventerInterface;

class SomeService
{
    public function createAction(EventerInterface $eventer)
    {
        $entity = $eventer
            ->repository($this->someRepository)
            ->create(['title' => 'Lorem']);
        
        // or
        $entity = $eventer
            ->repository(
                repository: $this->someRepository,
                immutableAttributes: true, // default is false
            )
            ->create(['title' => 'Lorem']);            
    }
}

Credits

统计信息

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

GitHub 信息

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

其他信息

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

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固