PHPackages                             webman-tech/common-utils - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. webman-tech/common-utils

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

webman-tech/common-utils
========================

v5.0.19(2mo ago)01.5k—3.1%20MITPHPPHP ^8.2

Since Nov 24Pushed 2mo agoCompare

[ Source](https://github.com/webman-tech/common-utils)[ Packagist](https://packagist.org/packages/webman-tech/common-utils)[ RSS](/packages/webman-tech-common-utils/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (2)Versions (24)Used By (20)

webman-tech/common-utils
========================

[](#webman-techcommon-utils)

本项目由 [webman-tech/components-monorepo](https://github.com/orgs/webman-tech/components-monorepo) 自动 split 得到，请勿在该仓库直接修改。

> 通用工具组件，聚焦“消除 Webman/Laravel/自定义环境差异”，为运行时、HTTP、配置、日志、测试等核心能力提供一致的 API。

核心特点
----

[](#核心特点)

- **统一运行时抽象**：`Runtime` + `RuntimeCustomRegister` 允许在 Webman、Laravel 与自定义进程中切换，实现路径、容器、日志等核心服务的自适应。
- **HTTP 全栈能力**：全新的 `Request`、`Response`、`Session`、`Route`、`Middleware\BaseMiddleware` 等类兼容 Webman/Symfony/Laravel 请求对象，并支持附加自定义数据。
- **配置与环境增强**：`Config` 支持闭包默认值、配置文件引入；`EnvAttr` 内置 env 文件自动加载、只读保护、系统变量优先级和 define 同步。
- **数据处理升级**：`Json` 自动处理 INF/NAN、非 UTF-8 字符以及 `Json\Expression`（注入 JS）；`Encoding` 递归修正编码；`View`提供纯 PHP 模板渲染。
- **测试友好**：`Testing\Factory` 一键注册自定义运行时，配套 `TestRequest/TestResponse/TestRoute/TestSession`等假体让单测可控、可清理。
- **丰富的 Helper**：`base_path()/runtime_path()/logger()/locale()/get_env()` 等函数开箱即用，帮助在业务层快速接入。

安装
--

[](#安装)

```
composer require webman-tech/common-utils
```

安装后无需额外配置，即可在 Webman、Laravel 或测试环境中直接使用。

快速体验
----

[](#快速体验)

```
use WebmanTech\CommonUtils\Request;
use WebmanTech\CommonUtils\Response;
use WebmanTech\CommonUtils\Json;

$request = Request::getCurrent();

$userId = $request->path('id');
$payload = $request->allPostJson();

$response = Response::make()
    ->withStatus(201)
    ->withHeaders(['X-Trace-Id' => $request->header('X-Trace-Id')])
    ->withBody(Json::encode(['id' => $userId, 'payload' => $payload]));

return $response->getRaw(); // 始终返回原生 Webman/Symfony 响应
```

功能模块
----

[](#功能模块)

### 运行时与基础设施

[](#运行时与基础设施)

- **Runtime / RuntimeCustomRegister**

    - `Runtime::isWebman()/isLaravel()/isWorkerman()/isCli()`：准确识别当前运行时，可通过 `Runtime::changeRuntime()`手动切换（测试/自定义场景）。
    - `RuntimeCustomRegister::register()`：为 `base_path/runtime_path/config_get/request/response/...`等关键服务注入自定义实现，完全脱离框架也能运行。
    - `Runtime::terminating()`：在支持的框架中注册请求结束回调。
- **Local**（路径与主机信息）

    - `getBasePath()/getRuntimePath()/getConfigPath()/getAppPath()/getVendorPath()`：统一返回路径并支持缓存，可通过自定义注册覆盖。
    - `combinePath()`：跨平台拼接路径。
    - `getIp()`：自动检测当前主机 IPv4（支持 Windows/Linux/macOS），也可通过 `LOCAL_IP` 环境变量强制指定。
- **EnvAttr**（环境变量控制台）

    - 自动加载 `env.local.php` 或 `env.php`，首次调用 `get()` 后默认变为只读，保证配置一致。
    - `changeSupportReadonly/changeSupportSysEnv/changeSupportDefine` 控制只读开关、系统变量优先级、define 支持。
    - `transToDefine()` 可批量把 env 写入常量，便于兼容老代码。
- **Config**

    - 支持 `Config::get('foo.bar', fn () => 'default')` 闭包默认值，未命中时才执行。
    - `Config::requireFromConfigPath('database')` 从当前运行时配置目录引入文件。
- **Helper 函数**

    - `base_path()/runtime_path()/config_path()/app_path()/vendor_path()` 使用 `Local`。
    - `get_env()/put_env()` 操作 `EnvAttr`；`config()` 直通 `Config`。
    - `logger()` 获取 `Log::channel()`；`locale()` 读取/设置语言。

### 容器、日志与语言

[](#容器日志与语言)

- **Container**：对接 Webman/Laravel/自定义容器，`get()/has()/make()` API 一致，原始容器可通过 `Container::getRaw()` 获取。
- **Log**：`Log::channel($name)` 自动路由到对应框架日志实例，测试环境默认落在 `Testing\TestLogger`。
- **Lang**：`Lang::getLocale()/setLocale()` 统一语言环境，在测试环境通过 `Testing\TestLang` 控制。

### HTTP 相关能力

[](#http-相关能力)

- **Request**

    - `Request::getCurrent()` 自动选择 Webman、Laravel、Symfony Request 或自注册对象。
    - `get()/post()/postForm()/postJson()/allGet()/allPostForm()/allPostJson()` 统一获得参数，包含 query、form-data、json、文件。
    - `path()` 读取路由参数，`header()/cookie()/rawBody()` 获取标准数据，`getContentType()` 自动转小写。
    - `getRoute()` 返回 `Route\RouteObject`，`getSession()` 返回 `Session` 封装。
    - `getUserIp()` 对 Webman/Symfony 做了真实 IP 解析；`getHost()` 返回访问域名。
    - `withHeaders()` 修改真实请求头；`withCustomData()/getCustomData()` 可挂载附加信息（Webman 中通过动态属性存储）。
- **Response**

    - `Response::make()` 根据运行时创建 Webman/Symfony/TestResponse；`Response::from()` 包装已有响应。
    - 链式调用 `withStatus()/withHeaders()/withBody()` 修改原生响应；`getStatusCode()/getBody()/getHeader()` 读取最终内容。
- **Session**

    - 自动适配 `Workerman\Session`、`Symfony\SessionInterface`、`Illuminate\Contracts\Session\Session` 等多种实现。
    - 提供统一的 `get()/set()/delete()`。
- **Route 与 RouteObject**

    - `Route::getCurrent()` 返回当前路由管理器（Webman 读取全局 Route，自定义环境使用 `Testing\TestRoute`）。
    - `addRoute()` 接收 `RouteObject`，可带 methods/path/callback/name/middlewares。
    - `getRouteByName()/getRoutes()` 支持按名称检索和批量遍历；`RouteObject::getUrl()` 可以调用底层路由器生成 URL。
    - `Route::clear()` 清理运行时路由（内置 `Testing\Webman\ClearableRoute`，解决单测间互相污染）。
- **Middleware\\BaseMiddleware**

    - 统一入口：Webman 调用 `process()`，Laravel 调用 `handle()`，最终都落入 `processRequest(Request $request, Closure $handler): Response`。
    - 通过 `Request/Response` 适配层，开发者只需要面向公共 API，实现的中间件即可跨框架复用。

### 数据处理与视图

[](#数据处理与视图)

- **Json**

    - `Json::encode()` 默认启用 `JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE`，同时支持：
        - 自动把 INF/NAN 转为 `0`（或在设置 `JSON_PARTIAL_OUTPUT_ON_ERROR` 后继续输出）。
        - 自动递归调用 `Encoding::toUTF8()`，在遇到非 UTF-8 字符时重试。
        - 将 `Json\Expression` 内联输出 JS 代码，常用于前后端混合渲染。
        - 对 `Iterator/JsonSerializable/SimpleXMLElement/DateTimeInterface/资源` 等类型做特殊处理。
    - `Json::decode()` 遇到 UTF-8 错误会自动尝试转码。
- **Encoding**

    - `Encoding::toUTF8()` 支持字符串、数组键值递归转换，对非 UTF-8 字符保底降级为 ASCII 字符，避免 JSON/Web 输出报错。
- **View**

    - `View::renderPHP($file, $data)` 以最小成本渲染 PHP 模板，捕获异常时会清理缓冲区，避免脏输出。

### 缓存

[](#缓存)

- **ArrayCache**
    - 符合 PSR-16 标准的内存数组缓存，适用于单次请求内的数据缓存。
    - 支持 TTL（过期时间）、默认 TTL 和最大 TTL 限制。
    - 支持 LRU 淘汰策略，当缓存数量达到上限时自动淘汰最久未使用的项。
    - 支持手动 GC 清理过期缓存。
    - 支持 PSR-20 时钟接口注入，便于单元测试。
    - 提供 `gc()`、`count()`、`keys()` 等辅助方法用于缓存管理。
- **NullCache**
    - 空缓存实现（Null Object 模式），所有操作都是空操作。
    - 用于禁用缓存或作为默认值，避免 null 检查。

测试工具箱
-----

[](#测试工具箱)

位于 `WebmanTech\CommonUtils\Testing` 命名空间，配合 `Testing\Factory` 构建完全可控的运行时：

- **Factory::registerTestRuntime($baseDir, $vendorDir)**

    - 将运行时切换为 `Runtime::changeRuntime(Constants::RUNTIME_CUSTOM)`，并对 base/runtime/config/app/vendor path、容器、配置、日志、语言、request/response/session/route 等关键服务全部注册测试实现。
    - 自动加载项目与插件配置、初始化数据库（如果 Webman 相关类存在）。
- **Test* 系列*\*

    - `TestRequest`：可通过 `setData()/setHeader()/setGet()/setPost()` 自定义任意输入，并支持 `withCustomData()`。
    - `TestResponse`：易于断言状态码、Header、Body。
    - `TestRoute/TestContainer/TestSession/TestLogger/TestLang`：帮助模拟底层组件，提供 `clear()/reset()` 用于隔离测试。
    - `Testing\Webman\ClearableRoute`：解决 Webman 全局路由无法回收的问题。

> 建议在单测入口处调用 `Factory::registerTestRuntime()`，然后通过 `Request::getCurrent()`/`Route::getCurrent()` 等公共 API 获取对应假体，这样测试代码与真实环境保持一致。

使用示例
----

[](#使用示例)

### 统一的中间件

[](#统一的中间件)

```
use WebmanTech\CommonUtils\Middleware\BaseMiddleware;
use WebmanTech\CommonUtils\Request;
use WebmanTech\CommonUtils\Response;

final class TraceMiddleware extends BaseMiddleware
{
    protected function processRequest(Request $request, \Closure $handler): Response
    {
        $request->withHeaders(['X-Request-Trace' => uniqid('trace_', true)]);

        $response = $handler($request);

        return $response->withHeaders(['X-Response-Time' => microtime(true)]);
    }
}
```

这段中间件既可以在 Webman `process()` 中注册，也可在 Laravel `handle()` 中使用，完全复用。

### 操作路由表

[](#操作路由表)

```
use WebmanTech\CommonUtils\Route;
use WebmanTech\CommonUtils\Route\RouteObject;

$route = Route::getCurrent();

$route->addRoute(new RouteObject(
    methods: ['GET', 'POST'],
    path: '/users/{id}',
    callback: [UserController::class, 'detail'],
    name: 'users.detail',
    middlewares: ['auth', 'throttle:60,1'],
));

$item = $route->getRouteByName('users.detail')
$detailUrl = $item->getUrl(['id' => 1]); // Webman 环境下可生成 /users/1
$detailUrl = $item->getUrl(['id' => 1], appendPrefix: true); // 如果项目在二级目录下，可以开启该配置，Webman 环境下可生成 /{YourPrefix}/users/1
```

### 加强版 env 管理

[](#加强版-env-管理)

```
use WebmanTech\CommonUtils\EnvAttr;

EnvAttr::reset();
EnvAttr::changeSupportReadonly(false);
EnvAttr::set('PAYMENT_GATEWAY', 'stripe');
EnvAttr::changeSupportSysEnv(false); // 让自定义 env 优先

$gateway = EnvAttr::get('PAYMENT_GATEWAY', fn () => 'fallback');

EnvAttr::changeSupportDefine(true);
EnvAttr::transToDefine(['exclude' => ['SENSITIVE_KEY']]);
```

### 内存缓存（单次请求内）

[](#内存缓存单次请求内)

```
use WebmanTech\CommonUtils\Cache\ArrayCache;

// 基本使用：无限制缓存
$cache = new ArrayCache();
$cache->set('user:123', ['id' => 123, 'name' => 'John']);
$user = $cache->get('user:123');

// 带过期时间：默认 TTL 1 小时，最大 TTL 24 小时
$cache = new ArrayCache(defaultTtl: 3600, maxTtl: 86400);
$cache->set('config:settings', $settings, 600); // 10 分钟过期

// LRU 淘汰：最多缓存 1000 项，超过时自动清理最久未使用的
$cache = new ArrayCache(maxItems: 1000);

// 手动清理过期缓存
$clearedCount = $cache->gc();

// 获取缓存统计
$count = $cache->count();
$keys = $cache->keys();
```

### 空缓存（禁用缓存）

[](#空缓存禁用缓存)

```
use WebmanTech\CommonUtils\Cache\NullCache;
use Psr\SimpleCache\CacheInterface;

// 作为依赖注入的默认值，避免 null 检查
class MyService
{
    public function __construct(
        private CacheInterface $cache = new NullCache()
    ) {}

    public function getData(string $key): mixed
    {
        return $this->cache->get($key) ?? $this->expensiveOperation($key);
    }
}

// 在测试中禁用缓存
$service = new MyService(new NullCache());
```

最佳实践
----

[](#最佳实践)

1. **只依赖公共 API**：应用代码中应调用 `Request/Response/Route/Container` 等抽象层，禁止直接引用具体框架类。
2. **运行时切换**：编写命令行或测试脚本时，先 `Runtime::changeRuntime()` 或调用 `Testing\Factory::registerTestRuntime()`，确保路径、容器等逻辑一致。
3. **善用辅助函数**：路径、配置、日志、语言的 Helper 能减少大量 `RuntimeCustomRegister` 判断。
4. **中间件场景**：`BaseMiddleware` 能确保修改请求头/自定义数据真实写回原请求对象，避免多框架行为不一致。
5. **Json/Encoding**：当需要序列化复杂数据时优先使用 `Json::encode()`，避免原生 `json_encode()` 触发 UTF-8/INF/NAN 错误。
6. **测试隔离**：测试完成后重置 `TestRequest/TestResponse/TestContainer/TestRoute`，或者使用内置 `clear()` 方法避免跨用例污染。

注意事项
----

[](#注意事项)

- 组件会根据当前运行时自动选择实现，若运行时不可识别且未通过 `RuntimeCustomRegister` 注入对应能力，将抛出 `InvalidArgumentException` 或 `UnsupportedRuntime`。
- `Request` / `Response` 没有转换成 PSR-7 对象，避免丢失原始请求引用；中间件中对原对象的修改（如 `withHeaders()`、 `withCustomData()`）会直接体现在真实请求上。
- `EnvAttr::get()` 首次调用会从 `env.local.php` 或 `env.php` 自动加载并默认进入只读模式，如需在运行时修改请先 `EnvAttr::changeSupportReadonly(false)`。
- `Route::clear()` 会清空 Webman 全局路由，仅在测试或 CLI 初始化时调用，线上环境慎用。

###  Health Score

48

—

FairBetter than 95% of packages

Maintenance86

Actively maintained with recent releases

Popularity21

Limited adoption so far

Community18

Small or concentrated contributor base

Maturity57

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~4 days

Total

23

Last Release

76d ago

Major Versions

v1.0.1 → v5.0.02025-11-24

### Community

Maintainers

![](https://www.gravatar.com/avatar/b4053cfc9956b8c15b9bc4c9c7c2bad625d16d1b6d9191019b2a25cc0972d955?d=identicon)[kriss](/maintainers/kriss)

---

Top Contributors

[![krissss](https://avatars.githubusercontent.com/u/10680903?v=4)](https://github.com/krissss "krissss (29 commits)")

### Embed Badge

![Health badge](/badges/webman-tech-common-utils/health.svg)

```
[![Health](https://phpackages.com/badges/webman-tech-common-utils/health.svg)](https://phpackages.com/packages/webman-tech-common-utils)
```

###  Alternatives

[illuminate/contracts

The Illuminate Contracts package.

705122.9M10.1k](/packages/illuminate-contracts)[phiki/phiki

Syntax highlighting using TextMate grammars in PHP.

3573.0M23](/packages/phiki-phiki)[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

728272.9k20](/packages/civicrm-civicrm-core)[flow-php/etl

PHP ETL - Extract Transform Load - Abstraction

374468.4k51](/packages/flow-php-etl)[gehrisandro/tailwind-merge-php

TailwindMerge for PHP merges multiple Tailwind CSS classes by automatically resolving conflicts between them

1391.5M9](/packages/gehrisandro-tailwind-merge-php)[posthog/posthog-php

PostHog PHP Library

293.5M9](/packages/posthog-posthog-php)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
