respect/fluent
Composer 安装命令:
composer require respect/fluent
包简介
Namespace-aware fluent class resolution
README 文档
README
Respect\Fluent
Build fluent interfaces from class namespaces. PHP 8.5+, zero dependencies.
Fluent maps method calls to class instances. You define classes in a namespace,
extend FluentBuilder, and get a chainable API where each call resolves a
class name, instantiates it, and accumulates it immutably.
$stack = Middleware::cors('*') ->rateLimit(100) ->auth('bearer') ->jsonBody(); $stack->getNodes(); // [Cors('*'), RateLimit(100), Auth('bearer'), JsonBody()]
Middlewares, validators, processors: anything that composes well as a chain can leverage Respect/Fluent.
Installation
composer require respect/fluent
Quick Start
1. Choose a namespace and interface
Fluent discovers classes from one or more namespaces. Giving them a shared interface lets your builder enforce type safety and expose domain methods.
namespace App\Middleware; interface Middleware { public function process(Request $request, Handler $next): Response; } final readonly class Cors implements Middleware { public function __construct(private string $origin = '*') {} public function process(Request $request, Handler $next): Response { /* ... */ } } final readonly class RateLimit implements Middleware { public function __construct(private int $maxRequests = 60) {} public function process(Request $request, Handler $next): Response { /* ... */ } } // etc...
2. Extend FluentBuilder
The #[FluentNamespace] attribute declares where your classes live and how to
resolve them. The builder inherits __call, immutable accumulation, and
withNamespace support, you only add domain logic:
namespace App; use Respect\Fluent\Attributes\FluentNamespace; use Respect\Fluent\Builders\Append; use Respect\Fluent\Factories\NamespaceLookup; use Respect\Fluent\Resolvers\Ucfirst; use App\Middleware\Middleware; #[FluentNamespace(new NamespaceLookup(new Ucfirst(), Middleware::class, 'App\\Middleware'))] final readonly class MiddlewareStack extends Append { public function __construct(Middleware ...$layers) { parent::__construct(static::factoryFromAttribute(), ...$layers); } /** @return array<int, Middleware> */ public function layers(): array { return $this->getNodes(); } }
The attribute carries the full factory configuration: the resolver (Ucfirst),
optional type constraint (Middleware::class), and namespace to search. The
inherited factoryFromAttribute() reads it at runtime so there's a single
source of truth.
Now MiddlewareStack::cors()->auth('bearer')->jsonBody() builds the
layers for you.
3. Add composition if you want
Prefix composition lets optionalAuth() create Optional(Auth()). You're
not limited to Optional cases, you can design nesting as deep as you want.
Annotate wrapper classes with #[Composable]:
namespace App\Middleware; use Respect\Fluent\Attributes\Composable; #[Composable(self::class)] final readonly class Optional implements Middleware { public function __construct(private Middleware $inner) {} public function process(Request $request, Handler $next): Response { // Skip the middleware if a condition is met return $this->shouldSkip($request) ? $next($request) : $this->inner->process($request, $next); } }
Then switch the attribute to use ComposingLookup, it automatically discovers
#[Composable] prefixes from the same namespace:
use Respect\Fluent\Factories\ComposingLookup; #[FluentNamespace(new ComposingLookup( new NamespaceLookup(new Ucfirst(), Middleware::class, 'App\\Middleware'), ))] final readonly class MiddlewareStack extends Append { /* ... */ }
Now MiddlewareStack::optionalAuth('bearer') creates Optional(Auth('bearer')).
4. Add custom namespaces
Users can extend your middleware stack with their own classes.
withNamespace is inherited from FluentBuilder:
$stack = MiddlewareStack::cors(); $extended = $stack->withNamespace('MyApp\\CustomMiddleware'); $extended->logging(); // Finds MyApp\CustomMiddleware\Logging
How It Works
Fluent has three layers:
- Resolvers transform method names before lookup (e.g.,
'email'→'Email', or'notEmail'→ wrapper'Not'+ inner'Email'). - Factories search namespaces for the resolved class name and instantiate it.
- Builders (
Append,Prepend) chain factory calls immutably via__call.
Resolved classes are called nodes because consumer libraries (like Respect/Validation) often arrange them into tree structures.
A FluentNode carries the resolution state between resolvers and factories: a name, constructor arguments, and an optional wrapper.
+----------+
'notEmail' --------> | Resolver | ------> FluentNode('Email', wrapper: FluentNode('Not'))
+----------+
|
v
+----------+
FluentNode ---------> | Factory | ------> Not(Email())
+----------+
NamespaceLookup vs ComposingLookup: use NamespaceLookup for simple
name-to-class mapping. Wrap it with ComposingLookup when you need prefix
composition like notEmail() → Not(Email()). ComposingLookup supports
recursive unwrapping, so notNullOrEmail() → Not(NullOr(Email())) works too.
Assurance attributes
Node classes can declare what they assure about their input via #[Assurance].
Assertion methods are marked with #[AssuranceAssertion], and #[AssuranceParameter]
identifies specific parameters. Constructor parameters for composition use
#[ComposableParameter].
This metadata is available at runtime through reflection and is also consumed by tools like FluentAnalysis for static type narrowing.
#[Assurance(type: 'int')] final readonly class IntType implements Validator { /* ... */ } final readonly class ValidatorBuilder extends Append { #[AssuranceAssertion] public function assert(#[AssuranceParameter] mixed $input): void { /* ... */ } #[AssuranceAssertion] public function isValid(#[AssuranceParameter] mixed $input): bool { /* ... */ } }
See Assurance, AssuranceParameter, ComposableParameter, and the enum
types in the API reference for the full set of options.
API Reference
See docs/api.md for the complete API reference covering attributes, builders, factories, resolvers, and exceptions.
respect/fluent 适用场景与选型建议
respect/fluent 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 375 次下载、GitHub Stars 达 1, 最近一次更新时间为 2026 年 03 月 23 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「fluent」 「respect」 「builder」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 respect/fluent 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 respect/fluent 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 respect/fluent 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Inspired 'KennedyTedesco Validation' - The power of 'Respect Validation' on Laravel.
Presentation and Formatting helper with nice fluent interface.
A Sphinx Query Builder extension for the Laravel Database package
The power of 'Respect Validation' on Laravel.
Anax Database Active Record module for model classes.
Traits gathering fluent syntax common methods
统计信息
- 总下载量: 375
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 34
- 依赖项目数: 3
- 推荐数: 1
其他信息
- 授权协议: ISC
- 更新时间: 2026-03-23