定制 haspadar/primus 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

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

haspadar/primus

最新稳定版本:v0.9.0

Composer 安装命令:

composer require haspadar/primus

包简介

Primitive wrappers for PHP: strong typing for strings, ints, arrays, and more

README 文档

README

Primus logo

CI Coverage Mutation testing badge PHPStan Level Psalm Level

Object‑Oriented PHP Primitives

Primus is a library of object‑oriented PHP primitives. It provides common operations as small composable objects instead of functions.

Procedural PHP buries the steps inside out — you read from the innermost call:

strtolower(trim(substr($s, 0, 5)));

Primus reads top to bottom — each step is a named object:

(new Lowered(
    new Trimmed(
        new Sub(new TextOf($s), 0, 5),
    ),
))->value();

The pipeline is a value itself: store it, pass it around, decorate it further. Reading the result is always explicit — call value().

Why?

  • null everywhere.
    PHP's standard library leaks null through array_search, preg_match, mb_strpos even if you ban it in your project. Primus values are never null — missing input fails fast.

  • Bare array shapes.
    Procedural functions take array/string and you re‑describe their shape with PHPDoc at every call site. In Primus the type lives in the class — each operation has a narrow constructor signature you write once.

  • Closures hard to substitute.
    A callable is convenient until you need to swap it in a test, log every call, or wrap it in retry logic. A Func/Predicate/BiFunc object composes like any other class.

  • Controlled flow.
    Procedural chains run as you write them. A Primus pipeline runs only when value() is called — building, passing and composing it costs nothing until you ask for the result.

Installation

composer require haspadar/primus

Text

To trim and lowercase:

$text = (new Lowered(new Trimmed(new TextOf('  Hello  '))))->value();
// "hello"

To take a substring:

$text = (new Sub(new TextOf('Hello, world!'), 0, 5))->value();
// "Hello"

Lists

To filter and sort:

$big = (new Sorted(
    new Filtered(
        new ListOf(3, 1, 4, 1, 5, 9, 2, 6),
        new PredicateOf(static fn (int $x): bool => $x > 2),
    ),
))->value();
// [3, 4, 5, 6, 9]

To pluck a column from a list of rows:

$names = (new Plucked(
    new ListOf(
        ['id' => 1, 'name' => 'Alice'],
        ['id' => 2, 'name' => 'Bob'],
    ),
    'name',
))->value();
// ['Alice', 'Bob']

Maps

To merge two maps with last‑wins precedence:

$merged = (new Merged(
    new MapOf(['a' => 1, 'b' => 2]),
    new MapOf(['b' => 99, 'c' => 3]),
))->value();
// ['a' => 1, 'b' => 99, 'c' => 3]

To index a list of rows by one column, with values from another:

$byId = (new PluckedBy(
    new ListOf(
        ['id' => 1, 'name' => 'Alice'],
        ['id' => 2, 'name' => 'Bob'],
    ),
    'id',
    'name',
))->value();
// [1 => 'Alice', 2 => 'Bob']

Scalars

To compose lazy boolean logic:

$between = (new And_(
    new GreaterThan(new Constant(5), new Constant(0)),
    new LessThan(new Constant(5), new Constant(10)),
))->value();
// true

To memoize an expensive computation:

$cached = new Sticky(
    new ScalarOf(static fn () => expensive_computation()),
);
$cached->value(); // expensive_computation() runs once
$cached->value(); // cached

Functions

To wrap a callable as a reusable, swappable object:

$double = new FuncOf(static fn (int $x): int => $x * 2);
$double->apply(21);
// 42

To memoize a function by its input:

$cached = new StickyFunc(
    new FuncOf(static fn (int $id): User => $repo->find($id)),
);
$cached->apply(1); // hits the repo
$cached->apply(1); // cached

To fall back to another function on failure:

$safe = new FuncWithFallback(
    new FuncOf(static fn (string $url): string => http_get($url)),
    new FuncOf(static fn (string $url): string => ''),
);

Design rules

  • No null, no static methods or properties, no isset()/empty()
  • All state readonly, all classes final
  • One class = one behavior; composition over inheritance
  • Computation is lazy until value()

Enforced by haspadar/sheriff — a curated bundle of PHPStan level 9, Psalm with custom EO rules, PHP‑CS‑Fixer, PHPMD, PHPMetrics, Infection, and repository lints.

Inspired by Elegant Objects and cactoos.

Requirements

PHP 8.3+.

License

MIT

统计信息

  • 总下载量: 3
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 4
  • 点击次数: 3
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-10-10

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固