Skip to content

Conversation

@huangdijia
Copy link
Contributor

@huangdijia huangdijia commented Oct 29, 2025

Summary

  • Add PHPStan configuration file for type assertion testing (phpstan.types.neon.dist)
  • Add type assertion tests for helper functions in types/Helpers/Functions.php
  • Add new composer script check:types for running type analysis

Details

This PR introduces a type checking infrastructure to validate type assertions for helper functions. The new PHPStan configuration uses max level analysis on the types/ directory, which contains type assertion tests using PHPStan's testing utilities.

Changes

  1. phpstan.types.neon.dist: PHPStan configuration file set to max level for type checking
  2. types/Helpers/Functions.php: Type assertion tests for base_path() and app() helper functions
  3. composer.json: New check:types script to run type analysis

Test plan

  • Run composer check:types to verify type assertions pass
  • Verify that the type assertions correctly validate helper function return types
  • Ensure PHPStan configuration works with the existing codebase

Summary by CodeRabbit

  • Chores

    • 添加用于运行静态类型分析的 Composer 脚本与专用配置,并在 CI 流程中新增类型测试步骤。
  • New Features

    • 补充请求、集合与字符串工具的公开 API 声明,扩展初始化、工厂、判断与转换等方法。
    • 新增若干轻量 Sentry 辅助类以支持集成与测试场景。
  • Refactor

    • 为若干工厂入口补充返回类型声明,明确公开签名。
  • Tests

    • 增加大量静态类型断言文件,作为类型文档与验证补充。

Add PHPStan configuration for type assertion testing and a new composer script for running type checks. This includes:
- New phpstan.types.neon.dist configuration file for type checking
- New types/ directory with helper function type assertions
- New composer script 'check:types' for running type analysis

This enhancement allows developers to validate type assertions for helper functions and ensure type safety across the codebase.
@coderabbitai
Copy link

coderabbitai bot commented Oct 29, 2025

Warning

Rate limit exceeded

@huangdijia has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 4 minutes and 54 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 0acc572 and de85c6e.

📒 Files selected for processing (1)
  • types/Cache/Repository.php (1 hunks)

Walkthrough

新增 PHPStan 类型检查脚本与配置,添加大量 types/* 静态类型断言文件,并引入/修改若干对外 API 签名(多数为占位实现或返回类型标注),涉及 Collection、LazyCollection、Request、Str/Stringable、Sentry 工厂与 Cache 支持类型断言。

Changes

Cohort / File(s) 变更摘要
构建/脚本
composer.json
新增 Composer 脚本 type-testing(执行 phpstan analyze --configuration="phpstan.types.neon.dist" --memory-limit=-1);微调 test:unit 行的逗号。
CI / Workflow
.github/workflows/tests.yaml
在 tests 流程中新增 "Run Type Tests" 步骤,执行 composer type-testing,插入到现有步骤序列中。
PHPStan 配置
phpstan.types.neon.dist
新增 PHPStan 配置,level = max,将 types 目录加入分析 paths 并列出扫描文件/规则片段。
静态类型断言 — Helpers / Support / Sentry / Cache / Macros / Str 等
types/... (例如 types/Helpers/Functions.php, types/Support/Support.php, types/Sentry/Sentry.php, types/Cache/*, types/Macros/*, types/Macros/Str.php, types/Macros/Stringable.php)
新增大量严格类型的 PHPStan 类型断言文件,覆盖 Helpers、Support、Sentry、Cache、Collection/LazyCollection/Arr/Request/Str/Stringable 等的返回类型与调用形态(仅静态断言/测试桩,无运行逻辑改动)。
API/签名新增 — Collection / LazyCollection / Request
src/macros/output/Hyperf/Collection/Collection.php, src/macros/output/Hyperf/Collection/LazyCollection.php, src/macros/output/Hyperf/HttpServer/Request.php
在 Collection 中添加公共构造函数 __construct($items = [])(空实现);在 LazyCollection 中添加静态工厂 make($items = []) 与实例方法 isSingle()(占位);新增 Hyperf\HttpServer\Request 类,声明大量公共方法签名(方法体为空,占位)。
API/签名变更 — Str / Stringable
src/macros/output/Hyperf/Stringable/Str.php, src/macros/output/Hyperf/Stringable/Stringable.php
Str 中新增 of($string), doesntEndWith, doesntStartWith,并为 createUuidsUsing / createUuidsNormally 明确返回 void;在 Stringable 中新增 doesntEndWithdoesntStartWith 实例方法(均为空实现/签名)。
签名类型标注 — Sentry 工厂
src/sentry/src/Factory/ClientBuilderFactory.php, src/sentry/src/Factory/HubFactory.php
为工厂类的 __invoke 方法添加返回类型注释:ClientBuilderHubInterface(仅签名变更,无逻辑改动)。

Sequence Diagram(s)

sequenceDiagram
    autonumber
    rect rgb(248,249,255)
    participant CI as CI Runner
    participant Composer as Composer
    participant PHPStan as PHPStan
    note right of CI #f8f9ff: 流程新增类型检查步骤
    end
    CI->>Composer: composer type-testing
    Composer->>PHPStan: phpstan analyze --configuration="phpstan.types.neon.dist"
    PHPStan-->>Composer: 类型检查报告 (通过/失败)
    Composer-->>CI: 退出码/日志
Loading
sequenceDiagram
    autonumber
    actor Dev as Developer
    participant Types as types/* files
    participant Src as src/* API stubs
    note over Dev, Types #f7fff0: 添加/修改以支持静态类型检查
    Dev->>Types: 新增类型断言与测试桩
    Dev->>Src: 增加签名/返回类型、占位实现
    Types->>PHPStan: 被分析(phpstan.types.neon.dist)
    Src->>PHPStan: 与断言一同被检查
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • 需重点审查:
    • types/* 中的断言是否与真实库签名严格匹配(Helpers、Request、Cache、Sentry、Collection 等)。
    • 新增/修改的公开方法签名(Request、Collection、LazyCollection、Str/Stringable)与现有框架接口兼容性。
    • phpstan.types.neon.dist 配置路径与扫描规则是否正确、composer script 的引号与语法正确性。
    • Sentry 工厂返回类型注释引入的类型依赖与导入是否完整。

Possibly related PRs

Poem

🐰 我在代码苔间跳,
类型断言轻声叫,
PHPStan 点亮长道,
签名与桩并肩跑,
胡萝卜旁,我笑眯眯。

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 65.15% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed 标题"feat: Add PHPStan type testing"清晰地反映了PR的核心目标——建立PHPStan类型检查框架。从raw_summary中可以看出,PR的主要改动包括:添加PHPStan配置文件(phpstan.types.neon.dist)、创建composer脚本(type-testing)、添加CI工作流步骤,以及创建多个类型测试文件(types/目录下的Helpers、Cache、Macros、Sentry、Support相关文件)。虽然PR还包含一些新增方法和返回类型注解的改动(如Collection、Request、Str等),但这些都是为了支持类型测试框架的完整建设而进行的。标题准确概括了这些改动的主要目的,并且足够具体,使得团队成员能够快速理解PR的关键功能。

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@huangdijia huangdijia marked this pull request as draft October 29, 2025 01:39
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
types/Helpers/Functions.php (1)

20-21: app() 的类型断言技术上正确,但可以考虑更精确的类型。

当前断言 app(Fluent::class) 返回 mixed 与函数签名一致。但是,如果 PHPStan 配置了 DI 容器的类型支持(通过扩展或存根),可以使用更精确的类型断言如 Fluent,这样能提供更好的类型检查覆盖。

可选的改进(如果 PHPStan 支持 DI 容器类型推断):

-assertType('mixed', app(Fluent::class));
+assertType('Hyperf\Support\Fluent', app(Fluent::class));

注意:仅在 PHPStan 能够通过扩展或存根推断 DI 容器返回类型时应用此更改。

composer.json (1)

314-314: 新增的 check:types 脚本配置正确!

脚本正确引用了新的 PHPStan 配置文件,并设置了无限内存以支持大型分析。命令结构符合项目约定。

可选的一致性改进:注意到第 313 行使用 analyse(英式拼写),而第 314 行使用 analyze(美式拼写)。虽然 PHPStan 两种拼写都支持,但为保持一致性,建议统一使用一种拼写:

-        "check:types": "phpstan analyze --configuration=\"phpstan.types.neon.dist\" --memory-limit=-1",
+        "check:types": "phpstan analyse --configuration=\"phpstan.types.neon.dist\" --memory-limit=-1",
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2255369 and b191b9a.

📒 Files selected for processing (3)
  • composer.json (1 hunks)
  • phpstan.types.neon.dist (1 hunks)
  • types/Helpers/Functions.php (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
composer.json

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Root composer.json should require PHP >=8.1

Files:

  • composer.json
**/*.php

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.php: Code style must follow PSR-12 and be formatted by PHP-CS-Fixer per .php-cs-fixer.php
Run PHPStan and keep the codebase passing per phpstan.neon.dist

Files:

  • types/Helpers/Functions.php
🧠 Learnings (1)
📚 Learning: 2025-10-12T13:53:35.783Z
Learnt from: CR
PR: friendsofhyperf/components#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-12T13:53:35.783Z
Learning: Applies to **/*.php : Run PHPStan and keep the codebase passing per phpstan.neon.dist

Applied to files:

  • phpstan.types.neon.dist
🧬 Code graph analysis (1)
types/Helpers/Functions.php (1)
src/helpers/src/Functions.php (2)
  • app (67-74)
  • base_path (79-82)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)
  • GitHub Check: Test on PHP 8.1 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.1 with Swoole 6.1.0
  • GitHub Check: Test on PHP 8.1 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.3 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.2 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.3 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.2 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.3 with Swoole 6.1.0
  • GitHub Check: Test on PHP 8.2 with Swoole 6.1.0
  • GitHub Check: Test on PHP 8.1 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.1 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.2 with Swoole 6.1.0
  • GitHub Check: Test on PHP 8.3 with Swoole 6.1.0
  • GitHub Check: Test on PHP 8.1 with Swoole 6.1.0
  • GitHub Check: Test on PHP 8.3 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.2 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.3 with Swoole 6.0.2
🔇 Additional comments (4)
types/Helpers/Functions.php (3)

1-10: 文件头部结构正确!

严格类型声明和标准文件头符合 PSR-12 规范和项目约定。


11-15: 导入语句准确且必要!

所有导入的类和函数都在后续的类型断言中使用,结构清晰。


17-18: base_path() 的类型断言正确!

类型断言准确反映了 base_path() 函数的返回类型(string),同时测试了有参数和无参数两种调用方式。

phpstan.types.neon.dist (1)

1-4: PHPStan 类型检查配置结构合理!

配置简洁明了:使用最高分析级别(max)并专注于 types/ 目录。将类型断言测试与主 PHPStan 配置分离是良好的实践,便于独立运行和维护。

@huangdijia
Copy link
Contributor Author

@copilot Complete other types testing in src/Helpers

Copy link
Contributor

Copilot AI commented Oct 29, 2025

@huangdijia I've opened a new pull request, #971, to work on those changes. Once the pull request is ready, I'll request review from you.

* Initial plan

* feat: add comprehensive type tests for all helper functions

Co-authored-by: huangdijia <8337659+huangdijia@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: huangdijia <8337659+huangdijia@users.noreply.github.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b191b9a and 894922f.

📒 Files selected for processing (2)
  • types/Helpers/Command/Functions.php (1 hunks)
  • types/Helpers/Functions.php (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • types/Helpers/Functions.php
🧰 Additional context used
📓 Path-based instructions (1)
**/*.php

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.php: Code style must follow PSR-12 and be formatted by PHP-CS-Fixer per .php-cs-fixer.php
Run PHPStan and keep the codebase passing per phpstan.neon.dist

Files:

  • types/Helpers/Command/Functions.php
🪛 GitHub Actions: tests
types/Helpers/Command/Functions.php

[error] 1-1: PHP CS Fixer reported formatting issues (2 fixes found). Run 'vendor/bin/php-cs-fixer fix' to apply fixes.

🔇 Additional comments (1)
types/Helpers/Command/Functions.php (1)

15-17: 类型断言正确。

call() 函数的类型断言符合预期,命令执行通常返回整数退出码。测试覆盖了有参数和无参数两种常见用法场景。

Deleted Command/Functions.php and moved its call() tests to Helpers/Functions.php. Updated type assertions and test cases in Helpers/Functions.php for improved accuracy and consistency with current return types.

Co-Authored-By: Deeka Wong <8337659+huangdijia@users.noreply.github.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
types/Helpers/Functions.php (1)

177-179: 考虑优化类型断言的精确度

根据 environment() 函数的实现逻辑:

  • 不带参数时返回 Environment 实例
  • 带参数时返回 bool (调用 is() 方法)

当前的联合类型 'bool|FriendsOfHyperf\Support\Environment' 对两种调用都使用可能不够精确。建议验证 PHPStan 是否能够更精确地推断:

  • Line 178: environment()FriendsOfHyperf\Support\Environment
  • Line 179: environment('production')bool

如果 PHPStan 无法静态区分这两种情况,当前的联合类型断言是合理的。

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 894922f and 59894aa.

📒 Files selected for processing (1)
  • types/Helpers/Functions.php (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.php

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.php: Code style must follow PSR-12 and be formatted by PHP-CS-Fixer per .php-cs-fixer.php
Run PHPStan and keep the codebase passing per phpstan.neon.dist

Files:

  • types/Helpers/Functions.php
🧬 Code graph analysis (1)
types/Helpers/Functions.php (4)
src/support/src/Environment.php (1)
  • Environment (28-64)
src/facade/src/Cookie.php (1)
  • Cookie (21-47)
src/helpers/src/Functions.php (21)
  • app (67-74)
  • base_path (79-82)
  • cache (110-129)
  • class_namespace (152-157)
  • cookie (136-145)
  • di (168-190)
  • enum_value (250-262)
  • environment (227-236)
  • literal (316-323)
  • logs (343-346)
  • now (355-358)
  • object_get (370-385)
  • preg_replace_array (390-397)
  • request (423-436)
  • rescue (481-492)
  • session (503-517)
  • throw_if (544-555)
  • throw_unless (570-581)
  • today (526-529)
  • transform (595-606)
  • validator (612-621)
src/facade/src/AsyncQueue.php (1)
  • AsyncQueue (22-40)
🪛 GitHub Actions: tests
types/Helpers/Functions.php

[error] 159-159: PHP CS Fixer fixable issue detected: change function parameter type from "\Throwable" to "Throwable" in the fail() method. Dry-run shows diff and process exited with code 8.

🔇 Additional comments (8)
types/Helpers/Functions.php (8)

1-49: LGTM!

文件头部和导入语句结构良好,所有必要的依赖都已正确导入。


50-67: 类型断言准确

app(), base_path(), blank(), cache() 函数的类型断言与实际实现一致。


69-83: 类型断言准确

class_namespace(), di(), enum_value(), event() 函数的类型断言与实际实现一致,包括对匿名类的正确处理。


85-98: 类型断言准确

filled(), fluent(), get_client_ip(), literal() 函数的类型断言正确,包括 literal() 命名参数用法的处理。


100-114: 类型断言准确

logger(), logs(), object_get(), preg_replace_array() 函数的类型断言与实际实现一致。


116-131: 类型断言准确

request(), rescue(), resolve(), response() 函数的类型断言正确,包括对异常处理和回退值的准确建模。


133-149: 类型断言准确

throw_if(), throw_unless(), transform(), validator(), when() 函数的类型断言正确,准确反映了条件逻辑和返回值。


151-158: 类型断言准确

cookie(), dispatch(), info(), now(), session(), today(), call() 函数的类型断言与实际实现一致。

Also applies to: 176-198

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5c47d7e and 1c809ee.

📒 Files selected for processing (1)
  • composer.json (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
composer.json

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Root composer.json should require PHP >=8.1

Files:

  • composer.json
🧠 Learnings (1)
📚 Learning: 2025-10-12T13:53:35.783Z
Learnt from: CR
PR: friendsofhyperf/components#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-12T13:53:35.783Z
Learning: Applies to **/*.php : Run PHPStan and keep the codebase passing per phpstan.neon.dist

Applied to files:

  • composer.json
🪛 GitHub Actions: tests
composer.json

[error] 1-1: Composer Normalize found that ./composer.json is not normalized. The diff shows changes to the scripts section (removal and re-addition of the 'type-testing' script) and the step 'composer normalize --dry-run --no-update-lock' failed with exit code 1.

@huangdijia
Copy link
Contributor Author

@copilot Add type testing for src/cache component.

Copy link
Contributor

Copilot AI commented Oct 29, 2025

@huangdijia I've opened a new pull request, #972, to work on those changes. Once the pull request is ready, I'll request review from you.

@huangdijia
Copy link
Contributor Author

@copilot Add type testing for src/macros component.

Copy link
Contributor

Copilot AI commented Oct 29, 2025

@huangdijia I've opened a new pull request, #973, to work on those changes. Once the pull request is ready, I'll request review from you.

@huangdijia huangdijia changed the title feat: add PHPStan type checking configuration and composer script feat: Add PHPStan type testing Oct 29, 2025
huangdijia and others added 3 commits October 29, 2025 13:13
* Initial plan

* feat: add type assertion tests for macros component

Co-authored-by: huangdijia <8337659+huangdijia@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: huangdijia <8337659+huangdijia@users.noreply.github.com>
Copilot AI and others added 5 commits October 29, 2025 13:26
* Initial plan

* feat: add comprehensive type testing for cache component

Co-authored-by: huangdijia <8337659+huangdijia@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: huangdijia <8337659+huangdijia@users.noreply.github.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/macros/output/Hyperf/Collection/LazyCollection.php (1)

14-41: 必须在 composer.json 中添加 exclude-from-classmap 以防止类覆盖风险

验证确认了审查意见的准确性。src/macros/output/Hyperf/Collection/LazyCollection.php 与 vendor/hyperf/collection/src/LazyCollection.php 命名空间完全相同,但 Composer 配置缺少 exclude-from-classmap,导致 src/macros/output 目录中的桩类有可能在运行时覆盖真实类。当前仅在 PHPStan 的 excludePaths 中排除分析,不足以保护生产环境。

需要修复

  1. composer.json 中添加 exclude-from-classmap 排除整个 src/macros/output 目录
  2. phpstan.neon.dist 中在 stubFiles 中显式声明这些文件为 PHPStan stub(或在 excludePaths 外补充说明)

建议参考 src/Collection/Collection.php 和其他同名文件的处理方式,确保所有在 output 目录中的桩类都得到正确隔离。

🧹 Nitpick comments (8)
src/macros/output/Hyperf/Collection/Collection.php (2)

25-41: 补齐返回类型与最小实现,避免运行时报错(示例补丁)

为与注释一致并降低误载入风险,建议最小实现:为 isSingle/collapseWithKeys 增加返回类型与返回值。

-    public function isSingle()
-    {
-    }
+    public function isSingle(): bool
+    {
+        return false; // stub: 与 macro 行为不完全等价,但满足类型
+    }
@@
-    public function collapseWithKeys()
-    {
-    }
+    public function collapseWithKeys(): static
+    {
+        return $this; // stub: 仅用于类型提示
+    }

21-23: 抑制未使用参数的静态分析噪音(可选)

构造函数仅为类型存在,可加抑制标注,或将参数改名为 $_items。

-    public function __construct($items = [])
+    /**
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function __construct($items = [])
     {
     }
src/macros/output/Hyperf/Collection/LazyCollection.php (1)

16-33: 为 make/isSingle/collapseWithKeys 提供最小实现与返回类型(示例补丁)

避免空方法导致类型与运行时不一致:

-    public static function make($items = [])
-    {
-    }
+    /**
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public static function make($items = []): static
+    {
+        return new static();
+    }
@@
-    public function isSingle()
-    {
-    }
+    public function isSingle(): bool
+    {
+        return false;
+    }

如有需要,也可为 collapseWithKeys 增加返回类型与最小返回:

-    public function collapseWithKeys()
-    {
-    }
+    public function collapseWithKeys(): static
+    {
+        return $this;
+    }
types/Sentry/Sentry.php (3)

111-114: PHPMD:$timeout 未使用,可显式消费以消除噪音(示例补丁)

类型测试桩实现里可用 void 强转消费参数。

-    public function close(?int $timeout = null): Result
+    public function close(?int $timeout = null): Result
     {
-        return new Result(ResultStatus::success());
+        (void) $timeout;
+        return new Result(ResultStatus::success());
     }

79-82: 构造参数可标记为 readonly(PHP ≥ 8.1,纯类型桩更语义化)

entries 未被修改,readonly 可避免无意赋值。

-    public function __construct(private array $entries)
+    public function __construct(private readonly array $entries)
     {
     }

83-96: (可选)PSR-11 异常类型一致性

DummyContainer::get 未找到时抛 RuntimeException。若希望更贴近规范,可抛实现 NotFoundExceptionInterface/ContainerExceptionInterface 的异常。鉴于这是类型测试桩,可忽略或后续优化。

types/Macros/Request.php (1)

16-109: 类型断言覆盖面良好,LGTM;可再补充 1-2 个断言(可选)

当前已覆盖大多数 Request 助手。可选改进:

  • 断言 getPsrRequest()/getSchemeAndHttpHost()/getHost()/getHttpHost 的返回类型(前两者已覆盖其一)。
  • 若未来引入 whenFilled/whenHas 的分支返回,补充对应 mixed/$this 的联合类型断言。
types/Macros/Collection.php (1)

15-18: 建议更新已弃用方法的测试

测试的 isSingle() 方法在对应的桩文件中标记为 @deprecated since v3.1,建议使用 containsOneItem 代替。考虑更新类型测试以使用推荐的方法,以确保测试覆盖的是长期维护的 API。

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3886513 and 6bf4907.

📒 Files selected for processing (19)
  • phpstan.types.neon.dist (1 hunks)
  • src/macros/output/Hyperf/Collection/Collection.php (1 hunks)
  • src/macros/output/Hyperf/Collection/LazyCollection.php (1 hunks)
  • src/macros/output/Hyperf/HttpServer/Request.php (1 hunks)
  • src/macros/output/Hyperf/Stringable/Str.php (2 hunks)
  • src/macros/output/Hyperf/Stringable/Stringable.php (1 hunks)
  • src/sentry/src/Factory/ClientBuilderFactory.php (1 hunks)
  • src/sentry/src/Factory/HubFactory.php (2 hunks)
  • types/Cache/Facade.php (1 hunks)
  • types/Cache/Manager.php (1 hunks)
  • types/Cache/Repository.php (1 hunks)
  • types/Macros/Arr.php (1 hunks)
  • types/Macros/Collection.php (1 hunks)
  • types/Macros/LazyCollection.php (1 hunks)
  • types/Macros/Request.php (1 hunks)
  • types/Macros/Str.php (1 hunks)
  • types/Macros/Stringable.php (1 hunks)
  • types/Sentry/Sentry.php (1 hunks)
  • types/Support/Support.php (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • phpstan.types.neon.dist
🧰 Additional context used
📓 Path-based instructions (2)
**/*.php

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.php: Code style must follow PSR-12 and be formatted by PHP-CS-Fixer per .php-cs-fixer.php
Run PHPStan and keep the codebase passing per phpstan.neon.dist

Files:

  • src/macros/output/Hyperf/Collection/Collection.php
  • types/Support/Support.php
  • types/Macros/Request.php
  • src/macros/output/Hyperf/Stringable/Stringable.php
  • types/Macros/Stringable.php
  • types/Macros/Str.php
  • src/sentry/src/Factory/HubFactory.php
  • types/Macros/LazyCollection.php
  • types/Macros/Collection.php
  • src/macros/output/Hyperf/Stringable/Str.php
  • types/Macros/Arr.php
  • src/sentry/src/Factory/ClientBuilderFactory.php
  • types/Cache/Manager.php
  • types/Sentry/Sentry.php
  • types/Cache/Facade.php
  • src/macros/output/Hyperf/Collection/LazyCollection.php
  • types/Cache/Repository.php
  • src/macros/output/Hyperf/HttpServer/Request.php
src/*/src/**/*.php

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

All component PHP code must use the namespace pattern FriendsOfHyperf{ComponentName}

Files:

  • src/sentry/src/Factory/HubFactory.php
  • src/sentry/src/Factory/ClientBuilderFactory.php
🧬 Code graph analysis (18)
src/macros/output/Hyperf/Collection/Collection.php (1)
src/http-client/src/PendingRequest.php (1)
  • __construct (243-263)
types/Support/Support.php (9)
src/support/src/Env.php (2)
  • Env (21-132)
  • getRepository (60-73)
src/support/src/Environment.php (2)
  • Environment (28-64)
  • is (58-63)
src/support/src/HtmlString.php (2)
  • HtmlString (17-57)
  • isNotEmpty (53-56)
src/support/src/Number.php (4)
  • Number (20-298)
  • parseInt (66-69)
  • parseFloat (77-80)
  • clamp (205-208)
src/support/src/Once.php (1)
  • Once (16-98)
src/support/src/Onceable.php (2)
  • Onceable (17-85)
  • tryFromTrace (37-46)
src/support/src/Sleep.php (6)
  • Sleep (27-489)
  • for (140-143)
  • sleep (177-180)
  • until (151-158)
  • and (276-281)
  • seconds (209-214)
src/support/src/Timebox.php (3)
  • Timebox (16-89)
  • returnEarly (63-68)
  • dontReturnEarly (75-80)
src/support/src/Functions.php (1)
  • once (71-79)
types/Macros/Request.php (2)
src/macros/output/Hyperf/HttpServer/Request.php (26)
  • Request (18-302)
  • boolean (44-46)
  • collect (51-53)
  • date (58-60)
  • enum (250-252)
  • exists (259-261)
  • filled (81-83)
  • float (85-87)
  • fluent (92-94)
  • hasAny (99-101)
  • host (127-129)
  • httpHost (138-140)
  • integer (291-293)
  • isEmptyString (106-108)
  • isJson (237-239)
  • isNotFilled (113-115)
  • keys (120-122)
  • missing (196-198)
  • str (270-272)
  • string (281-283)
  • wantsJson (212-214)
  • isSecure (158-160)
  • getScheme (154-156)
  • getPort (146-148)
  • schemeAndHttpHost (169-171)
  • anyFilled (32-34)
src/helpers/src/Functions.php (1)
  • request (423-436)
src/macros/output/Hyperf/Stringable/Stringable.php (3)
src/macros/output/Hyperf/Stringable/Str.php (2)
  • doesntEndWith (89-91)
  • doesntStartWith (100-102)
src/macros/src/StringableMixin.php (2)
  • doesntEndWith (85-89)
  • doesntStartWith (91-95)
src/macros/src/StrMixin.php (2)
  • doesntEndWith (76-81)
  • doesntStartWith (83-88)
types/Macros/Stringable.php (2)
src/macros/output/Hyperf/Stringable/Stringable.php (1)
  • Stringable (14-109)
src/macros/output/Hyperf/Stringable/Str.php (2)
  • Str (14-103)
  • of (23-25)
types/Macros/Str.php (1)
src/macros/output/Hyperf/Stringable/Str.php (9)
  • Str (14-103)
  • createUuidsNormally (37-39)
  • createUuidsUsing (30-32)
  • deduplicate (46-48)
  • inlineMarkdown (66-68)
  • markdown (56-58)
  • transliterate (78-80)
  • doesntEndWith (89-91)
  • doesntStartWith (100-102)
src/sentry/src/Factory/HubFactory.php (2)
src/sentry/src/Factory/ClientBuilderFactory.php (1)
  • __invoke (39-86)
src/sentry/src/ConfigProvider.php (1)
  • __invoke (16-77)
types/Macros/LazyCollection.php (1)
src/macros/output/Hyperf/Collection/LazyCollection.php (1)
  • LazyCollection (14-42)
types/Macros/Collection.php (1)
src/macros/output/Hyperf/Collection/Collection.php (1)
  • Collection (14-42)
src/macros/output/Hyperf/Stringable/Str.php (4)
src/macros/src/RequestMixin.php (1)
  • string (321-324)
src/macros/src/StrMixin.php (4)
  • createUuidsUsing (33-36)
  • createUuidsNormally (28-31)
  • doesntEndWith (76-81)
  • doesntStartWith (83-88)
src/macros/output/Hyperf/Stringable/Stringable.php (2)
  • doesntEndWith (96-98)
  • doesntStartWith (106-108)
src/macros/src/StringableMixin.php (2)
  • doesntEndWith (85-89)
  • doesntStartWith (91-95)
types/Macros/Arr.php (1)
src/macros/output/Hyperf/Collection/Arr.php (1)
  • Arr (17-132)
src/sentry/src/Factory/ClientBuilderFactory.php (2)
src/sentry/src/Factory/HubFactory.php (1)
  • __invoke (32-95)
src/sentry/src/ConfigProvider.php (1)
  • __invoke (16-77)
types/Cache/Manager.php (1)
src/cache/src/CacheManager.php (1)
  • CacheManager (21-58)
types/Sentry/Sentry.php (9)
src/sentry/src/Factory/ClientBuilderFactory.php (1)
  • ClientBuilderFactory (23-87)
src/sentry/src/Factory/HubFactory.php (1)
  • HubFactory (30-122)
src/sentry/src/Feature.php (8)
  • Feature (18-71)
  • isBreadcrumbEnabled (29-32)
  • isTracingEnabled (34-41)
  • isTracingSpanEnabled (43-50)
  • isTracingExtraTagEnabled (52-55)
  • isCronsEnabled (57-60)
  • disableCoroutineTracing (62-65)
  • isDisableCoroutineTracing (67-70)
src/sentry/src/Integration.php (5)
  • Integration (28-158)
  • sentryMeta (121-124)
  • sentryTracingMeta (129-138)
  • sentryBaggageMeta (144-147)
  • currentTracingSpan (154-157)
src/sentry/src/Integration/RequestFetcher.php (2)
  • RequestFetcher (18-34)
  • fetchRequest (20-33)
src/sentry/src/Switcher.php (2)
  • Switcher (19-85)
  • isExceptionIgnored (65-76)
src/sentry/src/Tracing/Tracer.php (1)
  • Tracer (27-94)
src/sentry/src/Version.php (3)
  • Version (16-31)
  • getSdkIdentifier (22-25)
  • getSdkVersion (27-30)
src/sentry/src/Function.php (1)
  • feature (24-27)
types/Cache/Facade.php (1)
src/facade/src/Facade.php (1)
  • Facade (18-82)
src/macros/output/Hyperf/Collection/LazyCollection.php (3)
src/macros/output/Hyperf/Collection/Collection.php (1)
  • isSingle (30-32)
src/macros/src/CollectionMixin.php (1)
  • isSingle (22-25)
src/macros/src/LazyCollectionMixin.php (1)
  • isSingle (23-26)
types/Cache/Repository.php (1)
src/cache/src/Repository.php (4)
  • Repository (44-463)
  • getMultiple (312-321)
  • setMultiple (359-362)
  • deleteMultiple (367-378)
src/macros/output/Hyperf/HttpServer/Request.php (2)
src/http-client/src/Http.php (1)
  • Http (106-217)
src/macros/output/Hyperf/Collection/Collection.php (1)
  • Collection (14-42)
🪛 GitHub Actions: tests
src/macros/output/Hyperf/Stringable/Str.php

[error] 1-1: PHP CS Fixer reported fixable issues in Str.php. Diff shown and step exited with code 8. Run 'vendor/bin/php-cs-fixer fix src/macros/output/Hyperf/Stringable/Str.php' to apply fixes.

🪛 PHPMD (2.15.0)
src/macros/output/Hyperf/Collection/Collection.php

21-21: Avoid unused parameters such as '$items'. (undefined)

(UnusedFormalParameter)

src/macros/output/Hyperf/Stringable/Stringable.php

96-96: Avoid unused parameters such as '$needles'. (undefined)

(UnusedFormalParameter)


106-106: Avoid unused parameters such as '$needles'. (undefined)

(UnusedFormalParameter)

src/macros/output/Hyperf/Stringable/Str.php

23-23: Avoid unused parameters such as '$string'. (undefined)

(UnusedFormalParameter)


30-30: Avoid unused parameters such as '$factory'. (undefined)

(UnusedFormalParameter)


89-89: Avoid unused parameters such as '$haystack'. (undefined)

(UnusedFormalParameter)


89-89: Avoid unused parameters such as '$needles'. (undefined)

(UnusedFormalParameter)


100-100: Avoid unused parameters such as '$haystack'. (undefined)

(UnusedFormalParameter)


100-100: Avoid unused parameters such as '$needles'. (undefined)

(UnusedFormalParameter)

types/Sentry/Sentry.php

111-111: Avoid unused parameters such as '$timeout'. (undefined)

(UnusedFormalParameter)

src/macros/output/Hyperf/Collection/LazyCollection.php

22-22: Avoid unused parameters such as '$items'. (undefined)

(UnusedFormalParameter)

src/macros/output/Hyperf/HttpServer/Request.php

32-32: Avoid unused parameters such as '$keys'. (undefined)

(UnusedFormalParameter)


44-44: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


44-44: Avoid unused parameters such as '$default'. (undefined)

(UnusedFormalParameter)


51-51: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


58-58: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


58-58: Avoid unused parameters such as '$format'. (undefined)

(UnusedFormalParameter)


58-58: Avoid unused parameters such as '$tz'. (undefined)

(UnusedFormalParameter)


67-67: Avoid unused parameters such as '$keys'. (undefined)

(UnusedFormalParameter)


74-74: Avoid unused parameters such as '$closure'. (undefined)

(UnusedFormalParameter)


81-81: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


85-85: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


85-85: Avoid unused parameters such as '$default'. (undefined)

(UnusedFormalParameter)


92-92: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


99-99: Avoid unused parameters such as '$keys'. (undefined)

(UnusedFormalParameter)


106-106: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


113-113: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


178-178: Avoid unused parameters such as '$input'. (undefined)

(UnusedFormalParameter)


187-187: Avoid unused parameters such as '$input'. (undefined)

(UnusedFormalParameter)


196-196: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


205-205: Avoid unused parameters such as '$keys'. (undefined)

(UnusedFormalParameter)


221-221: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


221-221: Avoid unused parameters such as '$callback'. (undefined)

(UnusedFormalParameter)


221-221: Avoid unused parameters such as '$default'. (undefined)

(UnusedFormalParameter)


230-230: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


230-230: Avoid unused parameters such as '$callback'. (undefined)

(UnusedFormalParameter)


230-230: Avoid unused parameters such as '$default'. (undefined)

(UnusedFormalParameter)


250-250: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


250-250: Avoid unused parameters such as '$enumClass'. (undefined)

(UnusedFormalParameter)


259-259: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


270-270: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


270-270: Avoid unused parameters such as '$default'. (undefined)

(UnusedFormalParameter)


281-281: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


281-281: Avoid unused parameters such as '$default'. (undefined)

(UnusedFormalParameter)


291-291: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


291-291: Avoid unused parameters such as '$default'. (undefined)

(UnusedFormalParameter)


295-295: Avoid unused parameters such as '$rules'. (undefined)

(UnusedFormalParameter)


295-295: Avoid unused parameters such as '$messages'. (undefined)

(UnusedFormalParameter)


295-295: Avoid unused parameters such as '$customAttributes'. (undefined)

(UnusedFormalParameter)


299-299: Avoid unused parameters such as '$errorBag'. (undefined)

(UnusedFormalParameter)


299-299: Avoid unused parameters such as '$rules'. (undefined)

(UnusedFormalParameter)


299-299: Avoid unused parameters such as '$messages'. (undefined)

(UnusedFormalParameter)


299-299: Avoid unused parameters such as '$customAttributes'. (undefined)

(UnusedFormalParameter)

🔇 Additional comments (16)
src/macros/output/Hyperf/Collection/Collection.php (1)

14-41: 配置检查无风险,原评论基于错误假设

经验证,src/macros/output/ 目录不存在 Composer 自动加载冲突风险:

  1. composer.json 中不包含该目录:仅 src/macros/src/ 被映射到 FriendsOfHyperf\Macros\src/macros/output/ 完全不在生产自动加载范围内。

  2. PHPStan 配置正确phpstan.types.neon.dist 使用 scanFiles(开发专用)加载这些桩文件,而非生产自动加载。

  3. 隔离设计生效:这些文件仅供 PHPStan 静态分析使用,生产代码不会加载,不存在命名空间覆盖风险。

原评论所述的"被 Composer 覆盖"和"运行时 TypeError"风险均不成立。当前配置已正确隔离开发桩文件与生产代码。

types/Macros/Arr.php (1)

1-58: 类型断言测试实现正确

这个文件为 Hyperf\Collection\Arr 的各种方法提供了完整的 PHPStan 类型断言测试,涵盖了标量类型获取、数组操作和集合判断等核心功能。所有断言都与对应的方法签名保持一致。

src/sentry/src/Factory/ClientBuilderFactory.php (1)

39-39: 显式返回类型声明提升了类型安全性

__invoke 方法添加了明确的 ClientBuilder 返回类型,这与方法体中通过 tap() 返回的实际类型一致,有助于 PHPStan 进行更准确的静态分析。

src/macros/output/Hyperf/Stringable/Stringable.php (1)

90-108: 类型检查桩方法实现符合预期

这两个新增的方法 doesntEndWith()doesntStartWith() 是用于 PHPStan 类型分析的桩方法,空方法体是符合预期的。它们的签名与 Str 类中的对应静态方法保持一致,为类型测试提供了必要的类型信息。

注意:PHPMD 报告的未使用参数警告可以忽略,这是桩方法的正常特征。

types/Macros/Collection.php (1)

20-22: LGTM!

collapseWithKeys() 方法的类型断言正确,测试覆盖了有数据和空数组两种场景。

src/sentry/src/Factory/HubFactory.php (1)

22-22: 显式返回类型声明提升了类型安全性

添加了 HubInterface 的导入和返回类型声明,与 ClientBuilderFactory 的改进保持一致。方法体返回的 Hub 实例正确实现了 HubInterface 接口,类型声明准确无误。

Also applies to: 32-32

types/Macros/Stringable.php (1)

1-44: 类型断言测试全面且正确

这个文件为 Stringable 类的多个方法提供了完整的类型测试,包括字符串处理、Markdown 转换、HTML 转换以及新增的字符串判断方法。所有断言都正确反映了方法的返回类型:

  • 大部分方法返回 Hyperf\Stringable\Stringable 实现链式调用
  • toHtmlString() 正确返回 FriendsOfHyperf\Support\HtmlString
  • 新增的 doesntEndWith()doesntStartWith() 返回 bool
types/Macros/LazyCollection.php (1)

1-22: LGTM!

LazyCollection 的类型断言测试实现正确,涵盖了静态工厂方法 make() 以及实例方法 isSingle()collapseWithKeys()。测试用例覆盖了空集合和有数据的场景,所有断言都与对应的方法签名保持一致。

types/Macros/Str.php (1)

1-44: LGTM!

Str 类的静态方法类型测试全面且正确:

  • UUID 相关方法(返回 void)通过直接调用进行测试
  • 字符串处理方法正确断言返回 string 类型
  • 新增的字符串比较方法 doesntEndWith()doesntStartWith() 正确断言返回 bool 类型
  • 测试覆盖了各种参数组合形式
types/Cache/Manager.php (1)

1-43: 类型断言正确!

类型测试文件正确地验证了 CacheManagerFactory 的返回类型。所有方法(store(), driver(), resolve())都正确断言返回 Repository 接口。

types/Cache/Facade.php (1)

1-92: 类型断言验证完整!

Facade 类型测试覆盖全面,正确验证了缓存门面的所有主要方法:

  • 存储/驱动选择方法返回 Repository
  • 基本 CRUD 操作返回正确的布尔值和混合类型
  • remember*flexible 方法正确推断闭包返回类型
  • 类型收窄(如 get() 使用默认值时)的断言正确
types/Cache/Repository.php (1)

1-116: Repository 类型断言准确!

类型测试全面覆盖了 Repository 接口和 CacheRepository 实现:

  • PSR-16 方法(get/set/delete/clear/getMultiple/setMultiple/deleteMultiple)类型正确
  • 扩展方法(put/putMany/add/forever/remember/flexible 等)断言准确
  • 泛型类型如 iterable<string, mixed> 正确标注
  • 驱动接口返回类型验证正确
types/Support/Support.php (1)

1-63: Support 工具类型测试完善!

类型断言正确验证了多个 Support 组件:

  • Once/Onceable 的单例和缓存机制类型正确
  • Timebox::call() 泛型返回类型正确推断
  • Sleep 构建器模式的链式调用类型准确
  • Number 解析和格式化方法的联合类型正确
  • HtmlStringEnvironmentEnv 的返回类型验证准确
src/macros/output/Hyperf/Stringable/Str.php (3)

30-30: LGTM!

正确添加了 void 返回类型声明,使方法签名更加明确。

Also applies to: 37-37


82-102: LGTM!新增的辅助方法签名正确。

doesntEndWith()doesntStartWith() 方法的签名和文档注释都正确。这些是占位方法,实际实现通过 StrMixin 宏动态注入。

注意:PHPMD 关于未使用参数的警告是预期的,因为这是一个存根文件,实际实现在 src/macros/src/StrMixin.php 中。


1-103: 无法验证实际的格式问题 - 需要手动确认 GitHub Actions 日志。

审查评论引用 Pipeline 失败但未提供具体的错误日志。从代码检查来看:

  • 文件存在且结构符合 PSR-12 标准
  • 已正确配置 .php-cs-fixer.php
  • 代码缩进、声明和格式在视觉检查上均无明显违规

由于沙盒环境无法执行 PHP CS Fixer 工具进行验证,请在本地环境中运行该命令并查看实际的 GitHub Actions 失败日志,以确认是否存在真实的格式问题需要修复。

Comment on lines +12 to +302
namespace Hyperf\HttpServer;

use Closure;
use Hyperf\Support\Fluent;
use Psr\Http\Message\ServerRequestInterface;

class Request
{
/**
* Get an array of all of the files on the request.
*/
public function allFiles(): array
{
}

/**
* Determine if the request contains a non-empty value for any of the given inputs.
*
* @param array|string $keys
*/
public function anyFilled($keys): bool
{
}

/**
* Retrieve input as a boolean value.
*
* Returns true when value is "1", "true", "on", and "yes". Otherwise, returns false.
*
* @param null|string $key
* @param bool $default
*/
public function boolean($key = null, $default = false): bool
{
}

/**
* Retrieve input from the request as a collection.
*/
public function collect(null|array|string $key = null): \Hyperf\Collection\Collection
{
}

/**
* Retrieve input from the request as a Carbon instance.
*/
public function date(string $key, ?string $format = null, ?string $tz = null): ?\Carbon\Carbon
{
}

/**
* Get all of the input except for a specified array of items.
*
* @param array|mixed $keys
*/
public function except($keys): array
{
}

/**
* @param null|Closure(ServerRequestInterface):ServerRequestInterface $closure
*/
public static function fake(?Closure $closure = null): ServerRequestInterface
{
}

/**
* Determine if the request contains a non-empty value for an input item.
*/
public function filled(array|string $key): bool
{
}

public function float(string $key, $default = null): float
{
}

/**
* Retrieve input from the request as a Fluent object instance.
*/
public function fluent(null|array|string $key = null): Fluent
{
}

/**
* Determine if the request contains any of the given inputs.
*/
public function hasAny(array|string $keys): bool
{
}

/**
* Determine if the given input key is an empty string for "has".
*/
public function isEmptyString(string $key): bool
{
}

/**
* Determine if the request contains an empty value for an input item.
*/
public function isNotFilled(array|string $key): bool
{
}

/**
* Get the keys for all of the input and files.
*/
public function keys(): array
{
}

/**
* Get the host name.
*/
public function host(): string
{
}

public function getHost(): string
{
}

/**
* Get the HTTP host being requested.
*/
public function httpHost(): string
{
}

public function getHttpHost(): string
{
}

public function getPort(): int
{
}

public function getPsrRequest(): ?ServerRequestInterface
{
}

public function getScheme(): string
{
}

public function isSecure(): bool
{
}

public function getSchemeAndHttpHost(): string
{
}

/**
* Get the scheme and HTTP host.
*/
public function schemeAndHttpHost(): string
{
}

/**
* Merge new input into the current request's input array.
*
* @return $this
*/
public function merge(array $input): self
{
}

/**
* Merge new input into the request's input, but only when that key is missing from the request.
*
* @return $this
*/
public function mergeIfMissing(array $input): self
{
}

/**
* Determine if the request is missing a given input item key.
*
* @param array|string $key
*/
public function missing($key): bool
{
}

/**
* Get a subset containing the provided keys with values from the input data.
*
* @param array|mixed $keys
*/
public function only($keys): array
{
}

/**
* Determine if the current request is asking for JSON.
*/
public function wantsJson(): bool
{
}

/**
* Apply the callback if the request contains a non-empty value for the given input item key.
*
* @return $this|mixed
*/
public function whenFilled(string $key, callable $callback, ?callable $default = null)
{
}

/**
* Apply the callback if the request contains the given input item key.
*
* @return $this|mixed
*/
public function whenHas(string $key, callable $callback, ?callable $default = null)
{
}

/**
* Determine if the request is sending JSON.
*/
public function isJson(): bool
{
}

/**
* Retrieve input from the request as an enum.
*
* @template TEnum
*
* @param string $key
* @param class-string<TEnum> $enumClass
* @return null|TEnum
*/
public function enum($key, $enumClass)
{
}

/**
* Determine if the request contains a given input item key.
*
* @param array|string $key
*/
public function exists($key): bool
{
}

/**
* Retrieve input from the request as a Stringable instance.
*
* @param string $key
* @param mixed $default
* @return \Hyperf\Stringable\Stringable
*/
public function str($key, $default = null)
{
}

/**
* Retrieve input from the request as a Stringable instance.
*
* @param string $key
* @param mixed $default
* @return \Hyperf\Stringable\Stringable
*/
public function string($key, $default = null)
{
}

/**
* Retrieve input as an integer value.
*
* @param string $key
* @param int $default
*/
public function integer($key, $default = 0): int
{
}

public function validate(array $rules, array $messages = [], array $customAttributes = []): array
{
}

public function validateWithBag(string $errorBag, array $rules, array $messages = [], array $customAttributes = []): array
{
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

阻止桩类在生产环境被自动加载:建议改为 PHPStan stubs 或排除 classmap

该文件声明了完整的 Hyperf\HttpServer\Request 桩类,方法均为空且大多带返回类型。一旦被 Composer 在运行时加载:

  • 会与真实类冲突或覆盖;
  • 空方法将触发 TypeError(有返回类型却无返回)。

建议:

  • 在 composer.json 的 autoload 段增加 exclude-from-classmap: ["src/macros/output/**"];
  • 或将本文件移至 dev-only 目录并通过 phpstan.types.neon.dist 的 stubFiles/scanFiles 引入;
  • 亦可采用 if (false) {...} 的“编译期桩”模式,仅供静态分析可见。

若短期无法迁移,请至少为这些方法提供统一兜底(如直接抛出 LogicException),防止误用:

示例(选取少量代表方法,其他方法同理处理):

-    public function allFiles(): array
-    {
-    }
+    public function allFiles(): array
+    {
+        throw new \LogicException('Stub for static analysis only.');
+    }

-    public function boolean($key = null, $default = false): bool
-    {
-    }
+    public function boolean($key = null, $default = false): bool
+    {
+        throw new \LogicException('Stub for static analysis only.');
+    }

-    public static function fake(?\Closure $closure = null): \Psr\Http\Message\ServerRequestInterface
-    {
-    }
+    public static function fake(?\Closure $closure = null): \Psr\Http\Message\ServerRequestInterface
+    {
+        throw new \LogicException('Stub for static analysis only.');
+    }

此外,可在需要处添加

  • @SuppressWarnings(PHPMD.UnusedFormalParameter) 以消除未使用参数告警;
  • 或将未使用参数命名为 $_key、$_input 等。Based on learnings

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 PHPMD (2.15.0)

32-32: Avoid unused parameters such as '$keys'. (undefined)

(UnusedFormalParameter)


44-44: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


44-44: Avoid unused parameters such as '$default'. (undefined)

(UnusedFormalParameter)


51-51: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


58-58: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


58-58: Avoid unused parameters such as '$format'. (undefined)

(UnusedFormalParameter)


58-58: Avoid unused parameters such as '$tz'. (undefined)

(UnusedFormalParameter)


67-67: Avoid unused parameters such as '$keys'. (undefined)

(UnusedFormalParameter)


74-74: Avoid unused parameters such as '$closure'. (undefined)

(UnusedFormalParameter)


81-81: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


85-85: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


85-85: Avoid unused parameters such as '$default'. (undefined)

(UnusedFormalParameter)


92-92: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


99-99: Avoid unused parameters such as '$keys'. (undefined)

(UnusedFormalParameter)


106-106: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


113-113: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


178-178: Avoid unused parameters such as '$input'. (undefined)

(UnusedFormalParameter)


187-187: Avoid unused parameters such as '$input'. (undefined)

(UnusedFormalParameter)


196-196: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


205-205: Avoid unused parameters such as '$keys'. (undefined)

(UnusedFormalParameter)


221-221: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


221-221: Avoid unused parameters such as '$callback'. (undefined)

(UnusedFormalParameter)


221-221: Avoid unused parameters such as '$default'. (undefined)

(UnusedFormalParameter)


230-230: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


230-230: Avoid unused parameters such as '$callback'. (undefined)

(UnusedFormalParameter)


230-230: Avoid unused parameters such as '$default'. (undefined)

(UnusedFormalParameter)


250-250: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


250-250: Avoid unused parameters such as '$enumClass'. (undefined)

(UnusedFormalParameter)


259-259: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


270-270: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


270-270: Avoid unused parameters such as '$default'. (undefined)

(UnusedFormalParameter)


281-281: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


281-281: Avoid unused parameters such as '$default'. (undefined)

(UnusedFormalParameter)


291-291: Avoid unused parameters such as '$key'. (undefined)

(UnusedFormalParameter)


291-291: Avoid unused parameters such as '$default'. (undefined)

(UnusedFormalParameter)


295-295: Avoid unused parameters such as '$rules'. (undefined)

(UnusedFormalParameter)


295-295: Avoid unused parameters such as '$messages'. (undefined)

(UnusedFormalParameter)


295-295: Avoid unused parameters such as '$customAttributes'. (undefined)

(UnusedFormalParameter)


299-299: Avoid unused parameters such as '$errorBag'. (undefined)

(UnusedFormalParameter)


299-299: Avoid unused parameters such as '$rules'. (undefined)

(UnusedFormalParameter)


299-299: Avoid unused parameters such as '$messages'. (undefined)

(UnusedFormalParameter)


299-299: Avoid unused parameters such as '$customAttributes'. (undefined)

(UnusedFormalParameter)

🤖 Prompt for AI Agents
In src/macros/output/Hyperf/HttpServer/Request.php lines 12-302: this file is a
full runtime-declarable stub (empty methods with return types) which can be
autoloaded in production causing class conflicts or TypeErrors; fix by moving
the file out of production classmap or making it compile-time only: add
"exclude-from-classmap": ["src/macros/output/**"] to composer.json autoload, or
relocate the stub to a dev-only folder and register it only for static analysis
(phpstan.stubFiles/scanFiles), or wrap the entire class declaration in if
(false) { ... } so it’s ignored at runtime; if you cannot immediately move it,
make each method fail-safe at runtime by throwing a LogicException (or similar)
from every method to avoid returning wrong types, and annotate/rename unused
parameters (or add @SuppressWarnings annotations) to silence static analysis
warnings.

Comment on lines 16 to 25
/**
* Return the remainder of a string after the first occurrence of a given value.
*
* @param string $subject
* @param string $search
* @return Stringable
*/
public static function of($string)
{
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

修正方法文档注释。

of() 方法的文档注释有误。当前文档说明为 "Return the remainder of a string after the first occurrence of a given value",但这不是 of() 方法的功能。of() 方法应该是创建一个 Stringable 实例的工厂方法。

应用此 diff 修正文档注释:

-    /**
-     * Return the remainder of a string after the first occurrence of a given value.
-     *
-     * @param string $subject
-     * @param string $search
-     * @return Stringable
-     */
+    /**
+     * Get a new stringable object from the given string.
+     *
+     * @param string $string
+     * @return Stringable
+     */
     public static function of($string)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* Return the remainder of a string after the first occurrence of a given value.
*
* @param string $subject
* @param string $search
* @return Stringable
*/
public static function of($string)
{
}
/**
* Get a new stringable object from the given string.
*
* @param string $string
* @return Stringable
*/
public static function of($string)
{
}
🧰 Tools
🪛 PHPMD (2.15.0)

23-23: Avoid unused parameters such as '$string'. (undefined)

(UnusedFormalParameter)

🤖 Prompt for AI Agents
In src/macros/output/Hyperf/Stringable/Str.php around lines 16 to 25, the
docblock for the of() method is incorrect (it describes returning the remainder
after a search); update the PHPDoc to describe that of() is a static factory
that creates and returns a Stringable instance from a given string, change the
summary line accordingly, ensure @param is "$string string" and @return is
"Stringable", and remove the incorrect description text.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/macros/output/Hyperf/Stringable/Str.php (1)

16-24: 修正方法文档注释。

of() 方法的文档注释不正确。当前描述为 "Return the remainder of a string after the first occurrence of a given value",但 of() 是一个创建 Stringable 实例的工厂方法。

建议应用以下修正:

-    /**
-     * Return the remainder of a string after the first occurrence of a given value.
-     *
-     * @param mixed $string
-     * @return Stringable
-     */
+    /**
+     * Get a new stringable object from the given string.
+     *
+     * @param mixed $string
+     * @return Stringable
+     */
     public static function of($string)
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6bf4907 and 0acc572.

📒 Files selected for processing (4)
  • .github/workflows/tests.yaml (1 hunks)
  • src/macros/output/Hyperf/Stringable/Str.php (2 hunks)
  • types/Cache/Manager.php (1 hunks)
  • types/Cache/Repository.php (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • types/Cache/Manager.php
🧰 Additional context used
📓 Path-based instructions (2)
.github/workflows/{tests,docs-split,docs-translate,release,split}.yaml

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

CI/CD workflows should be maintained via the specified GitHub Actions YAML files

Files:

  • .github/workflows/tests.yaml
**/*.php

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.php: Code style must follow PSR-12 and be formatted by PHP-CS-Fixer per .php-cs-fixer.php
Run PHPStan and keep the codebase passing per phpstan.neon.dist

Files:

  • types/Cache/Repository.php
  • src/macros/output/Hyperf/Stringable/Str.php
🧬 Code graph analysis (2)
types/Cache/Repository.php (1)
src/cache/src/Repository.php (3)
  • Repository (44-463)
  • getMultiple (312-321)
  • deleteMultiple (367-378)
src/macros/output/Hyperf/Stringable/Str.php (4)
src/macros/src/RequestMixin.php (1)
  • string (321-324)
src/macros/src/StrMixin.php (4)
  • createUuidsUsing (33-36)
  • createUuidsNormally (28-31)
  • doesntEndWith (76-81)
  • doesntStartWith (83-88)
src/macros/output/Hyperf/Stringable/Stringable.php (2)
  • doesntEndWith (96-98)
  • doesntStartWith (106-108)
src/macros/src/StringableMixin.php (2)
  • doesntEndWith (85-89)
  • doesntStartWith (91-95)
🪛 PHPMD (2.15.0)
src/macros/output/Hyperf/Stringable/Str.php

22-22: Avoid unused parameters such as '$string'. (undefined)

(UnusedFormalParameter)


29-29: Avoid unused parameters such as '$factory'. (undefined)

(UnusedFormalParameter)


88-88: Avoid unused parameters such as '$haystack'. (undefined)

(UnusedFormalParameter)


88-88: Avoid unused parameters such as '$needles'. (undefined)

(UnusedFormalParameter)


99-99: Avoid unused parameters such as '$haystack'. (undefined)

(UnusedFormalParameter)


99-99: Avoid unused parameters such as '$needles'. (undefined)

(UnusedFormalParameter)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)
  • GitHub Check: Test on PHP 8.1 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.2 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.1 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.2 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.1 with Swoole 6.1.0
  • GitHub Check: Test on PHP 8.3 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.3 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.2 with Swoole 6.1.0
  • GitHub Check: Test on PHP 8.3 with Swoole 6.1.0
  • GitHub Check: Test on PHP 8.2 with Swoole 6.1.0
  • GitHub Check: Test on PHP 8.3 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.1 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.2 with Swoole 5.1.8
  • GitHub Check: Test on PHP 8.2 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.1 with Swoole 6.0.2
  • GitHub Check: Test on PHP 8.1 with Swoole 6.1.0
  • GitHub Check: Test on PHP 8.3 with Swoole 6.1.0
🔇 Additional comments (6)
.github/workflows/tests.yaml (1)

85-86: 验证完成:工作流脚本名称正确,无需修改。

脚本验证表明 composer.json 中定义的实际脚本名称为 type-testing(第 338 行),而非 PR 目标中提到的 check:types。工作流步骤(第 85-86 行)正在使用正确的脚本名称 composer type-testing。此外,内存限制已在 composer 脚本定义中配置为 -1(无限制),无需在工作流步骤中另外配置。

代码变更与 composer.json 中的实际配置一致,不存在问题。

src/macros/output/Hyperf/Stringable/Str.php (2)

26-38: LGTM!

UUID 相关方法的签名和文档注释正确,void 返回类型声明准确。


81-101: LGTM!

新增的 doesntEndWith()doesntStartWith() 方法的签名、参数和返回类型声明都正确,文档注释清晰准确。

types/Cache/Repository.php (3)

1-20: 类型测试文件结构正确。

文件头、导入和变量声明符合 PHPStan 类型测试的标准模式。


22-49: 类型断言覆盖全面且准确。

基本 CRUD 操作、批量操作、自增/自减以及驱动获取方法的类型断言都正确反映了实际的返回类型:

  • 布尔返回值的方法(has, missing, set, delete, clear, put, forget, flush 等)
  • increment/decrementbool|int 返回类型正确反映了失败返回 false、成功返回新值的行为
  • getDriver/getStore 返回 DriverInterface 类型正确

类型覆盖全面,包含了接口和具体实现的测试。

Also applies to: 54-89, 109-116


58-58: 所有的类型断言都得到了正确的泛型支持,无需修改。

经过验证,Contract\Repository 接口中所有相关方法都包含完整的 @template TCacheValue 泛型注解:

  • pull() 方法支持从参数 $default 推断类型,当传入字符串时返回 string
  • remember()rememberForever()sear()flexible() 方法都支持从闭包返回类型 Closure(): TCacheValue 推断返回类型

测试文件中的 $repository 变量使用了接口类型注解 /** @var Repository $repository */,PHPStan 能够基于接口的泛型声明进行正确的类型推断,使得所有 assertType() 断言都能够通过验证。

@huangdijia huangdijia marked this pull request as ready for review October 29, 2025 06:22
@huangdijia huangdijia merged commit 7d207e3 into main Oct 29, 2025
22 checks passed
@huangdijia huangdijia deleted the feat/add-phpstan-type-checking branch October 29, 2025 06:23
huangdijia added a commit that referenced this pull request Oct 29, 2025
* feat: add PHPStan type checking configuration and composer script

Add PHPStan configuration for type assertion testing and a new composer script for running type checks. This includes:
- New phpstan.types.neon.dist configuration file for type checking
- New types/ directory with helper function type assertions
- New composer script 'check:types' for running type analysis

This enhancement allows developers to validate type assertions for helper functions and ensure type safety across the codebase.

* Add comprehensive PHPStan type tests for all helper functions (#971)

* Initial plan

* feat: add comprehensive type tests for all helper functions

Co-authored-by: huangdijia <8337659+huangdijia@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: huangdijia <8337659+huangdijia@users.noreply.github.com>

* Move call() tests to Functions.php and update type assertions

Deleted Command/Functions.php and moved its call() tests to Helpers/Functions.php. Updated type assertions and test cases in Helpers/Functions.php for improved accuracy and consistency with current return types.

Co-Authored-By: Deeka Wong <8337659+huangdijia@users.noreply.github.com>

* fix: remove unnecessary backslash from Throwable type hint in dispatch job

* refactor: rename check:types script to type-testing for clarity

* fix: move type-testing script to the correct position in composer.json

* fix: remove unnecessary blank line before type-testing script in composer.json

* feat: add Support.php with various utility classes and type assertions

* fix: add return type hints for __invoke methods in ClientBuilderFactory and HubFactory

* feat: add PHPStan type assertion tests for macros component (#973)

* Initial plan

* feat: add type assertion tests for macros component

Co-authored-by: huangdijia <8337659+huangdijia@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: huangdijia <8337659+huangdijia@users.noreply.github.com>

* feat: add PHPStan type testing for cache component (#972)

* Initial plan

* feat: add comprehensive type testing for cache component

Co-authored-by: huangdijia <8337659+huangdijia@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: huangdijia <8337659+huangdijia@users.noreply.github.com>

* fix: remove unused imports in Cache and Macros components

* feat: update PHPStan configuration and enhance type assertions in various components

* fix: update parameter type hint for Str::of method

* fix: remove unused Factory method tests in Cache Manager

* feat: add type testing step in CI workflow

* fix: comment out unused setMultiple tests in Repository

* fix: comment out unused getMultiple tests in Repository

---------

Co-Authored-By: Deeka Wong <8337659+huangdijia@users.noreply.github.com>
Co-Authored-By: Copilot <198982749+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants