perf: filter discovery tokenizes the app and system `Config/Filters.php` on every request
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 新手友好度
- 72/100
- Issue 类型
- 重构
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- php
- 领域
- backend, performance
调研方向
从私有方法 discoverFilters() 开始,它由 Filters 构造函数调用。查看 FileLocator::search() 的结果如何传递给 getClassname()。在该调用之前添加一项检查,跳过 APPPATH 和 SYSTEMPATH 下的 Config/Filters.php 路径,其他路径保持不变。运行 tests/system/Filters/FiltersTest.php。完成的标准是:通过 Services::injectMock('locator', ...) 注入的 spy locator 不再对应用或系统文件产生 getClassname() 调用,同时 tests/_support 中的自定义过滤器及其别名 test-customfilter 仍然可以正常工作。
由索引模型根据 Issue 内容生成。
描述
Problem
Filters::__construct() calls the deprecated discoverFilters() on every request when filter discovery is on, which it is by default. That method finds every Config/Filters.php across all namespaces. For each file, it calls FileLocator::getClassname(), which runs file_get_contents() and token_get_all() on the file.
In a default app, discovery finds only two files:
app/Config/Filters.phpsystem/Config/Filters.php
Both get read and tokenized, and then both are skipped, because their class is Config\Filters or CodeIgniter\Config\Filters. So every request pays to parse two files it never uses.
Measurements
PHP 8.3 on macOS, OPcache on, production mode, warm. Each number is averaged over 300 runs.
| Case | Time |
|---|---|
new Filters(...), discovery on (default) |
~103 µs |
new Filters(...), discovery off |
~0.2 µs |
FileLocator::search('Config/Filters.php') |
~15 µs |
FileLocator::getClassname() per file |
~42 µs |
For a full request to a bare closure route, Services::filters() is about 126 µs. That's the largest single cost left once #10615 lands, at about 14–18% of the request.
Proposal
In discoverFilters(), compare each found path against APPPATH . 'Config/Filters.php' and SYSTEMPATH . 'Config/Filters.php' before calling getClassname(). Skip those two paths with no file read.
FileLocator::search()already returns real paths, andAPPPATHandSYSTEMPATHare real paths too, so a plain string compare works.- Every other file keeps today's class-name check, unchanged. Module and package discovery files are still included as they are now.
With the default setup, the cost drops to the search() call alone, about 15 µs.
Compatibility
- No public or protected API changes.
discoverFilters()is private. - There's one edge case. Today, if
app/Config/Filters.phpdeclared some class other thanConfig\Filters, discovery wouldincludeit. After this change, that file is skipped. This layout breaks the framework's own conventions, and filter discovery has been deprecated since 4.4.2. So no changelog or upgrade-guide entry is planned.
Tests
Add a regression test in tests/system/Filters/FiltersTest.php. It uses a spy FileLocator, injected with Services::injectMock('locator', ...), that records the paths passed to getClassname(). The test asserts that:
getClassname()is never called for the app or systemConfig/Filters.php.getClassname()is still called fortests/_support/Config/Filters.php, and thetest-customfilteralias it adds is still registered.
The existing discovery test (FiltersTest.php:488) keeps covering the third-party path.
Related
- #10615. It covers config construction cost. This issue is independent and can land separately.
- 主要语言
- PHP
- 星标
- 6k
- 派生
- 2k
- 平均合并
- 1 天 22 小时
- 30 天内合并 PR
- 59
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
codeigniter4/CodeIgniter4 的其他 Issue
-
难度 4/5 3-5 天 新手友好度 35/100
codeigniter4/CodeIgniter4#10618 ·
维护者通常 1 天内回复
-
难度 3/5 1-2 天 新手友好度 62/100
codeigniter4/CodeIgniter4#10617 · 1 条评论 ·
维护者通常 1 天内回复
-
难度 4/5 3-5 天 新手友好度 25/100
codeigniter4/CodeIgniter4#10615 · 1 条评论 ·
维护者通常 1 天内回复
-
bug
难度 4/5 3-5 天 新手友好度 48/100
codeigniter4/CodeIgniter4#10589 · 3 条评论 ·
维护者通常 1 天内回复
-
dev
难度 5/5 一周以上 新手友好度 25/100
codeigniter4/CodeIgniter4#10427 · 5 条评论 ·
维护者通常 1 天内回复
查看 codeigniter4/CodeIgniter4 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 78/100
components-web-app/api-components-bundle#403 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 74/100
mollie/PrestaShop#1566 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 72/100
components-web-app/docs#193 ·
-
docs: add Python and PHP examples to docs/api.md可能已有人在做 @gaurika-analyst 今天认领。 未关闭documentation good first issue
难度 2/5 1-3 小时 新手友好度 85/100
djazairdev/wilayas#12 · 1 条评论 ·
维护者通常 1 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 68/100
endoflife-date/endoflife.date#11314 ·
维护者通常 1 天内回复