承接 talleu/php-redis-om 相关项目开发

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

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

talleu/php-redis-om

Composer 安装命令:

composer require talleu/php-redis-om

包简介

A PHP object mapper library for Redis

README 文档

README

Build Status PHPStan Packagist Version GitHub codecov.io Code Coverage

php-redis-om 🗄️

A PHP object mapper for Redis.

An Object Mapper for Redis®, designed to providing an intuitive and familiar interface for PHP developers to interact with Redis.

Features 🛠️

  • Doctrine-like methods and architecture
  • Symfony bundle integration
  • Easy integration with existing PHP applications
  • High performance and scalability with Redis®
  • Support for Redis JSON module
  • Automatic schema generation
  • Search and query capabilities with range filters
  • Auto-expiration of your objects
  • PHP enum support (backed enums)
  • Identity map and dirty tracking with partial updates
  • Atomic transactions (MULTI/EXEC)
  • Unique constraints (single-field and composite)
  • Pagination with total count
  • Memory-efficient streaming of large collections
  • Bulk delete and update without loading objects into memory
  • GEO queries (radius search)
  • Pipeline batch reads
  • API Platform support (beta)

Requirements ⚙️

  • PHP 8.2 or higher
  • Redis 4.0 or higher
  • Redisearch module (available by default with Redis >8 or in redis-stack distribution) (installation)
  • php-redis extension OR Predis library
  • Redis JSON module (optional, include in redis-stack)
  • Composer

Supported types ✅

  • scalar (string, int, float, bool, double)
  • PHP backed enums (string and int)
  • timestamp
  • json
  • null
  • DateTimeImmutable
  • DateTime
  • array and nested arrays
  • object and nested objects
  • stdClass

Installation 📝

Install the library via Composer:

composer require talleu/php-redis-om

Depending on your configuration, use phpredis or Predis

Symfony bundle 🎵

In a Symfony application, you may need to add this line to config/bundles.php

    Talleu\RedisOm\Bundle\TalleuRedisOmBundle::class => ['all' => true],

And that's it, your installation is complete ! 🚀

API Platform support 🕷️

For API Platform users, a basic implementation is provided here: API Platfom X Redis

Basic Usage 🎯

Add the RedisOm attribute to your class to map it to a Redis schema:

<?php

use Talleu\RedisOm\Om\Mapping as RedisOm;

#[RedisOm\Entity]
class User
{
    #[RedisOm\Id]
    #[RedisOm\Property]
    public int $id;

    #[RedisOm\Property(index:true)]
    public string $name;

    #[RedisOm\Property]
    public \DateTimeImmutable $createdAt;
}

After add the RedisOm attribute to your class, you have to run the following command to create the Redis schema for your classes (default path is ./src):

For Symfony users:

bin/console redis-om:migrate 

For others PHP applications:

vendor/bin/redisMigration <YOUR DIRECTORY PATH>

Then you can use the ObjectManager to persist your objects from Redis ! 💪

For Symfony users, just inject the RedisObjectManagerInterface in the constructor:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Talleu\RedisOm\Om\RedisObjectManagerInterface;
use App\Entity\Book;

class MySymfonyController extends AbstractController
{
    public function __construct(private RedisObjectManagerInterface $redisObjectManager)
    {}
    
    #[Route('/', name: 'app_home')]
    public function index(): Response
    {
        $book = new Book();
        $book->name = 'Martin Eden';
        $this->redisObjectManager->persist($book);
        $this->redisObjectManager->flush();

       //..
    }
}

For others PHP applications:

<?php

use Talleu\RedisOm\Om\RedisObjectManager;

$user = new User()
$user->id = 1;
$user->name = 'John Doe';

// Persist the object in redis
$objectManager = new RedisObjectManager();
$objectManager->persist($user);
$objectManager->flush();

🥳 Congratulations, your PHP object is now registered in Redis !

You can now retrieve your user wherever you like using the repository provided by the Object Manager (or the object manager directly):

// Retrieve the object from redis 
$user = $this->redisObjectManager->find(User::class, 1);
$user = $this->redisObjectManager->getRepository(User::class)->find(1);
$user = $this->redisObjectManager->getRepository(User::class)->findOneBy(['name' => 'John Doe']);

// Retrieve a collection of objects
$users = $this->redisObjectManager->getRepository(User::class)->findAll();
$users = $this->redisObjectManager->getRepository(User::class)->findBy(['name' => 'John Doe'], ['createdAt' => 'DESC'], 10);

Enum Support 🏷️

PHP backed enums are natively supported:

enum Status: string
{
    case ACTIVE = 'active';
    case INACTIVE = 'inactive';
}

#[RedisOm\Entity]
class Task
{
    #[RedisOm\Id]
    #[RedisOm\Property]
    public int $id;

    #[RedisOm\Property(index: true)]
    public Status $status;
}

Search by enum value:

$activeTasks = $repository->findBy(['status' => 'active']);

Range Queries 🔢

Use MongoDB-style operators for numeric range searches:

// Age between 18 and 65
$users = $repository->findBy(['age' => ['$gte' => 18, '$lte' => 65]]);

// Price greater than 100
$products = $repository->findBy(['price' => ['$gt' => 100]]);

// Score less than 50
$results = $repository->findBy(['score' => ['$lt' => 50]]);

// Combine with exact match
$results = $repository->findBy(['name' => 'John', 'age' => ['$gte' => 18]]);

Supported operators: $gte (>=), $gt (>), $lte (<=), $lt (<).

Note: Range queries work automatically with HASH format (NUMERIC index is auto-generated for int/float). For JSON format, you must explicitly declare a NUMERIC index: #[Property(index: ['age' => 'NUMERIC'])].

Pagination 📄

$paginator = $repository->paginate(
    criteria: ['status' => 'active'],
    page: 2,
    itemsPerPage: 20,
    orderBy: ['createdAt' => 'DESC']
);

$paginator->getItems();        // Current page items
$paginator->getTotalItems();   // Total matching count
$paginator->getTotalPages();   // Total number of pages
$paginator->getCurrentPage();  // Current page number
$paginator->hasNextPage();     // bool
$paginator->hasPreviousPage(); // bool

// Iterable
foreach ($paginator as $item) {
    // ...
}

Partial Updates (Merge) ⚡

Instead of re-persisting the entire object, use merge() to only update changed fields:

$user = $objectManager->find(User::class, 1);
$user->name = 'New Name'; // Only this field changed

$objectManager->merge($user);  // Detects change, updates only 'name'
$objectManager->flush();

For new objects (not loaded via find()), merge() falls back to a full persist().

Batch Reads (Pipeline) 🚀

Load multiple objects by ID in a single Redis pipeline call:

$users = $repository->findMultiple([1, 2, 3, 4, 5]);

GEO Queries 🌍

Search objects within a geographic radius (requires a GEO-indexed property):

#[RedisOm\Property(index: ['location' => 'GEO'])]
public string $location; // Format: "longitude,latitude"

$nearby = $repository->findByGeoRadius('location', 2.3522, 48.8566, 10, 'km');

Unique Constraints 🔒

Enforce uniqueness on one or more fields using #[Unique].

Single field:

#[RedisOm\Entity]
class User
{
    #[RedisOm\Id]
    #[RedisOm\Property]
    public int $id;

    #[RedisOm\Property(index: true)]
    #[RedisOm\Unique]
    public string $email;
}

Composite (combination of fields must be unique):

#[RedisOm\Entity]
#[RedisOm\Unique(properties: ['username', 'tenantId'])]
class User
{
    #[RedisOm\Id]
    #[RedisOm\Property]
    public int $id;

    #[RedisOm\Property]
    public string $username;

    #[RedisOm\Property]
    public int $tenantId;
}

flush() throws UniqueConstraintViolationException on conflict. Violations within the same flush() call are detected before hitting Redis. Concurrent writes are protected via Redis WATCH/MULTI/EXEC.

use Talleu\RedisOm\Exception\UniqueConstraintViolationException;

try {
    $objectManager->persist($user);
    $objectManager->flush();
} catch (UniqueConstraintViolationException $e) {
    // $e->getMessage() describes the conflicting field(s) and value(s)
}

Bulk Operations ⚡

Delete or update large numbers of objects without loading them into PHP memory.

$repository = $objectManager->getRepository(User::class);

// Delete all inactive users — unique-constraint keys are cleaned up automatically
$deleted = $repository->bulkDelete(['status' => 'inactive']);

// Update a scalar field on many objects at once
$updated = $repository->bulkUpdate(['country' => 'FR'], ['currency' => 'EUR']);

bulkUpdate() throws BulkOperationException when $changes targets a #[Unique] field. Use stream() + merge() + flush() instead for those cases.

Streaming Large Collections 🌊

findAll() loads everything into memory. stream() fetches objects in batches and yields them one by one, keeping memory bounded regardless of collection size.

// Via repository — full control
foreach ($repository->stream(['status' => 'active'], batchSize: 500) as $user) {
    // process $user — break works normally
}

// Via object manager — identity map is cleared automatically between batches
foreach ($objectManager->stream(User::class, ['status' => 'active']) as $user) {
    // process $user
}

Advanced documentation 📚

talleu/php-redis-om 适用场景与选型建议

talleu/php-redis-om 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 15.22k 次下载、GitHub Stars 达 200, 最近一次更新时间为 2024 年 06 月 05 日, 在 PHP 生态内属于活跃度较高的组件。

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

围绕 talleu/php-redis-om 我们能提供哪些服务?
定制开发 / 二次开发

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

  • 总下载量: 15.22k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 201
  • 点击次数: 15
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 200
  • Watchers: 5
  • Forks: 14
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2024-06-05