后端Web框架【免费下载链接】CodeIgniter4Open Source PHP Framework (originally from EllisLab)项目地址https://gitcode.com/gh_mirrors/co/CodeIgniter4点击查看免费下载本篇技术指南以 CodeIgniter 4 官方升级文档user_guide_src/source/installation/upgrade_412.rst为主体系统梳理从 4.1.1 升级到 4.1.2 时必须面对的所有破坏性变更Breaking Changes、增强性变更Breaking Enhancements与项目文件更新要点。你将掌握current_url()与indexPage行为变化的影响范围、缓存键校验规则、BaseConnection::query()返回值语义的修正、ConnectionInterface::isWriteType()新声明以及测试命名空间从「类继承」向「Trait 组合」的迁移方案。文中所有结论均对照当前仓库源码system/目录进行印证确保升级决策有据可查。升级前必读按安装方式选择迁移路径4.1.2 的升级说明并不提供「一键式」步骤而是要求你先确认自己的安装方式再进入对应的升级流程Composer 安装 App Starter 的用户请参考 Composer 安装的 App Starter 升级指南Composer 方式将 CodeIgniter4 添加到既有项目的用户请参考 向既有项目添加 CodeIgniter4 的升级指南手动安装Manual Installation的用户请参考 手动安装升级指南。无论采用哪种方式4.1.2 的核心变更集中在四类破坏性变更、一类接口增强和测试体系重构上下面逐一展开。破坏性变更一current_url() 与 indexPage 行为修正变更背景4.1.2 修复了 issue #4116 中current_url()存在的一个缺陷此前该函数生成 URI 时可能未按项目的Config\App::$indexPage配置包含入口脚本如index.php导致生成的 URL 与项目实际配置不一致。查看当前仓库中 system/Helpers/url_helper.php 的实现可以看到修正后的逻辑function current_url(bool $returnObject false, ?IncomingRequest $request null): string|URI { $request ?? service(request); /** var CLIRequest|IncomingRequest $request */ $uri $request-getUri(); return $returnObject ? $uri : URI::createURIString($uri-getScheme(), $uri-getAuthority(), $uri-getPath()); }current_url()直接基于IncomingRequest::getUri()返回的SiteURI对象构造结果。而indexPage是否拼接、如何拼接由 system/HTTP/SiteURI.php 中的$indexPage属性构造函数读取$configApp-indexPage见 SiteURI.php以及getIndexPageRoutePath()方法决定——当indexPage非空时入口脚本会被拼入路由路径SiteURI.php。修复后项目配置的indexPage会正确反映到current_url()的输出中。默认配置下app/Config/App.php中public string $indexPage index.php;见 app/Config/App.php。影响范围与升级动作官方文档明确指出凡是使用了App::$indexPage的项目以下依赖current_url()的组件都会产生不同的返回值必须重新核对输出Response Testing响应测试断言Pager分页器生成的链接Form Helperform_open()等表单辅助函数View Parser视图解析器中基于当前 URL 的占位替换升级动作升级后运行全量测试对依赖current_url()及其同源函数site_url()、base_url()实现见 url_helper.php的断言和页面链接进行回归检查若此前手动「绕过」了indexPage缺失问题例如在代码里自行拼接index.php应在升级后移除这类补偿逻辑避免重复拼接。破坏性变更二缓存键Cache Keys统一校验规则变更背景4.1.2 之前不同缓存驱动File、Redis、Memcached、APCu、Wincache、Predis 等对缓存键的兼容性差异很大。本次升级让所有缓存驱动统一对键进行校验规则基本对齐 PSR-6 建议键必须是至少一个字符的字符串用于唯一标识缓存项实现库必须支持由A-Z、a-z、0-9、_、.组成、UTF-8 编码、长度不超过 64 字符的键实现库可以额外支持其他字符、编码或更长的长度但至少要满足上述最低要求实现库负责对键字符串做必要的转义但必须能够原样返回未修改的键字符串以下字符为保留字符专为将来扩展而保留实现库不得支持{}()/\:源码印证BaseHandler::validateKey()仓库中所有缓存驱动system/Cache/Handlers 目录下的FileHandler.php、RedisHandler.php、MemcachedHandler.php、ApcuHandler.php、WincacheHandler.php、PredisHandler.php在get()、save()、delete()等入口统一调用BaseHandler::validateKey()进行键校验。BaseHandler的校验实现system/Cache/Handlers/BaseHandler.php包含三个层次public static function validateKey($key, $prefix ): string { if (! is_string($key)) { throw new InvalidArgumentException(Cache key must be a string); } if ($key ) { throw new InvalidArgumentException(Cache key cannot be empty.); } $reserved config(Cache::class)-reservedCharacters; if ($reserved ! strpbrk($key, $reserved) ! false) { throw new InvalidArgumentException(Cache key contains reserved characters . $reserved); } // If the key with prefix exceeds the length then return the hashed version return strlen($prefix . $key) static::MAX_KEY_LENGTH ? $prefix . md5($key) : $prefix . $key; }要点解读非字符串键如数字、对象直接抛出InvalidArgumentException空字符串键同样被拒绝保留字符的集合来自Config\Cache::$reservedCharacters默认值为{}()/\:见 app/Config/Cache.php可通过修改应用配置覆盖当「前缀 键」超过MAX_KEY_LENGTH时自动改用md5($key)哈希版本既保证长度合规又保持确定性MAX_KEY_LENGTH默认定义为PHP_INT_MAXBaseHandler.php即长度校验主要由各底层驱动与 PSR-6 的 64 字符建议共同约束。升级动作官方文档要求扫描并移除项目中所有包含{}()/\:保留字符或为空的非法缓存键。典型的高危场景包括用序列化数组、JSON 片段或带斜杠的路径如user/123/profile直接作为缓存键用空格拼接的多段键。建议为键设计统一规范例如user.{id}.profile注意避免使用保留字符可用_或.代替并在升级后对缓存读写路径做全量回归测试。破坏性变更三BaseConnection::query() 返回值语义修正变更背景4.1.2 之前BaseConnection::query()在查询失败时也会错误地返回BaseResult对象调用方很难区分「失败」与「空结果集」。本次升级修正了这一行为查询失败时返回false若DBDebug为true则直接抛出DatabaseException写类型查询Write-type query成功时返回布尔值true读类型查询成功时仍返回对应的 Result 对象。源码印证query() 的完整返回路径查看 system/Database/BaseConnection.php 的query()实现执行阶段通过simpleQuery()得到原始结果捕获DatabaseException时置$this-resultID falseBaseConnection.php失败分支中若$this-DBDebug为真且不在事务内或事务配置为抛异常重新抛出原始异常否则返回falseBaseConnection.php成功分支中先调用isWriteType($sql)判断语句类型写类型直接return true读类型则构造对应驱动 Result 类返回BaseConnection.php。从源码结构看整个判定链是执行 → 失败→抛异常 | false→ 成功 → 写类型→ true | Result 对象。isWriteType()如何判定写类型BaseConnection::isWriteType()的默认实现system/Database/BaseConnection.php使用正则匹配 SQL 开头关键字public function isWriteType($sql): bool { return (bool) preg_match(/^\s*(WITH\s.(\s|[)]))??(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX|MERGE)\s(?!.*\sRETURNING\s)/is, $sql); }可见INSERT、UPDATE、DELETE、REPLACE、CREATE、DROP、TRUNCATE、ALTER、RENAME、GRANT、REVOKE、LOCK、UNLOCK等关键字开头的语句都被归为写类型同时用负向断言排除了「以RETURNING结尾」的语句PostgreSQL 中INSERT ... RETURNING可返回数据属于读语义。各数据库驱动的 Connection 子类如 system/Database/MySQLi/Connection.php、system/Database/Postgre/Connection.php可以根据方言覆写isWriteType()升级审查时应同时查看这些覆写。升级动作逐一审查代码中所有直接调用query()的位置判断其返回值现在是false、true还是 Result 对象// 旧代码4.1.1 及以前失败也可能拿到 Result 对象容易掩盖错误 $result $db-query(SELECT * FROM users); // 新代码4.1.2必须区分写/读与成败 if ($db-query(DELETE FROM logs WHERE id 1) true) { // 写操作成功 } $result $db-query(SELECT * FROM users); if ($result false) { // 查询失败DBDebug false 时 } else { $rows $result-getResult(); }特别注意如果DBDebug为false失败时只会得到false而不是异常任何「拿到 Result 再调用方法」的旧代码都可能触发「对布尔值调用方法」的致命错误必须全部改为显式判空/判失败。破坏性增强一ConnectionInterface::isWriteType() 声明加入接口若你自行实现了ConnectionInterface自定义数据库驱动现在必须实现新加入的方法public function isWriteType($sql): bool如果你的类继承自BaseConnection基类已提供基本的isWriteType()实现见上文正则通常无需改动但可以按需覆写若类直接实现ConnectionInterface则需补齐该方法才能通过接口契约PHP 的接口方法签名一致性约束否则会在类加载时报错。破坏性增强二测试体系迁移到 Trait 组合变更背景4.1.2 对CodeIgniter\Test命名空间做了显著改进测试扩展从「继承特定测试基类」迁移为Trait 组合让开发者按需挑选能力避免继承树的耦合。具体变化CIDatabaseTestCase类被弃用其方法迁移到DatabaseTestTraitFeatureTestCase类被弃用其方法迁移到FeatureTestTraitControllerTester被ControllerTestTrait取代以统一测试方式并利用全新的响应测试能力。迁移示例来自升级文档的 literalinclude 代码升级前数据库测试继承专用基类?php use CodeIgniter\Test\DatabaseTestCase; class MyDatabaseTest extends DatabaseTestCase { public function testBadRow() { // ... } }升级后改为继承统一的CIUnitTestCase并混入DatabaseTestTrait?php use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\DatabaseTestTrait; class MyDatabaseTest extends CIUnitTestCase { use DatabaseTestTrait; public function testBadRow() { // ... } }上述两个代码片段即仓库中的 upgrade_412/001.php 与 upgrade_412/002.php。源码印证Trait 的实际能力当前仓库中这些 Trait 均已就位system/Test/DatabaseTestTrait.php提供数据库迁移migrateDatabase()、种子seed()/setUpSeed()等能力并内置$doneMigration、$doneSeed静态标记确保迁移/播种只执行一次见 DatabaseTestTrait.phpsystem/Test/FeatureTestTrait.php提供完整的 HTTP 全链路测试能力如withRoutes()覆盖路由、模拟请求与会话等system/Test/ControllerTestTrait.php以链式风格测试控制器典型用法为$this-withRequest($request)-withResponse($response)-withUri($uri)-withBody($body)-controller(App\Controllers\Home)-execute(methodName)见该类文件头注释。此外框架的测试环境自动加载配置system/Config/AutoloadConfig.php中仍保留着对CIDatabaseTestCase的 classmap 映射指向system/Test/CIDatabaseTestCase.php从源码结构看这是为了兼容旧类名、避免升级瞬间大面积报错新代码应一律使用 Trait 组合不要再依赖弃用类。迁移动作清单将继承CIDatabaseTestCase的测试类改为继承CIUnitTestCase并use DatabaseTestTrait将继承FeatureTestCase的测试类改为继承CIUnitTestCase并use FeatureTestTrait将使用ControllerTester的测试改为use ControllerTestTrait运行测试套件确认迁移后行为一致。破坏性增强三TestResponse 统一响应测试对象4.1.2 将响应测试工具整合升级新的TestResponsesystem/Test/TestResponse.php取代了原来的ControllerResponse与FeatureResponse合并了两者的方法集与属性集。绝大多数场景下这些变化由ControllerTestTrait和FeatureTestTrait在后台透明处理但有两个使用层面的变化必须知晓属性访问受限TestResponse的$request与$response属性改为protected见 TestResponse.php只能通过 getter 方法request()与response()访问TestResponse.php$request $result-request(); // 不再是 $result-request $response $result-response(); // 不再是 $result-response不再有 getBody()/setBody()TestResponse删除了getBody()与setBody()改经 Response 对象直接操作// 旧方式已移除 // $body $result-getBody(); // 新方式 $body $result-response()-getBody();同时TestResponse内置了对DOMParser的集成——构造时若响应体非空会自动加载 DOM 解析器TestResponse.php便于后续做 DOM 断言。它还提供了isOK()等便捷状态检查TestResponse.php只认可 200399 的状态码。项目文件Project Space更新建议推荐合并更新的文件4.1.2 对项目空间根目录、app、public、writable的若干文件做了实质性改动含弃用标记或视觉调整由于这些文件位于system之外框架不会自动替你修改需要手动合并。文档建议优先合并以下文件app/Config/App.phpapp/Config/Autoload.phpapp/Config/Cookie.phpapp/Config/Events.phpapp/Config/Exceptions.phpapp/Config/Security.phpapp/Views/errors/html/*envspark注官方文档同时提到社区有一些第三方 CodeIgniter 模块可在 Packagist 上以 codeigniter4 updates 为主题检索可辅助合并项目空间改动采用与否取决于你的项目约束。全部变更文件清单以下是 4.1.2 中项目空间收到改动的完整文件清单其中许多只是注释或格式调整不影响运行时行为app/Config/App.phpapp/Config/Autoload.phpapp/Config/ContentSecurityPolicy.phpapp/Config/Cookie.phpapp/Config/Events.phpapp/Config/Exceptions.phpapp/Config/Logger.phpapp/Config/Mimes.phpapp/Config/Modules.phpapp/Config/Security.phpapp/Controllers/BaseController.phpapp/Views/errors/html/debug.cssapp/Views/errors/html/error_404.phpapp/Views/errors/html/error_exception.phpapp/Views/welcome_message.phpcomposer.jsoncontributing/guidelines.rstenvpublic/.htaccesspublic/index.phpspark变更优先级说明官方文档特别说明除极少数用于修复 bug 的情况外项目空间文件的改动不会破坏你的应用。上述所有变更在下一个大版本之前都是「可选」的任何强制性的破坏性变更都已在前面的章节current_url()、缓存键、query()返回值、isWriteType()接口、测试体系覆盖完毕。因此合理的升级顺序是先处理破坏性变更代码层确保应用运行与测试通过再按清单合并项目空间文件配置层保持与官方默认骨架一致最后运行完整测试套件与冒烟测试重点回归分页、表单、视图解析与响应断言。升级自检清单完成 4.1.2 升级后建议对照以下清单逐项确认current_url()及其依赖组件分页器、表单辅助函数、视图解析器、响应测试的输出是否已按indexPage配置正确变化所有缓存键均为非空字符串且不含{}()/\:保留字符非法键已清理所有$db-query()调用已按「失败返回 false / 写操作返回 true / 读操作返回 Result」的新语义处理自定义ConnectionInterface实现已补齐isWriteType($sql): bool测试类已从CIDatabaseTestCase/FeatureTestCase/ControllerTester迁移到CIUnitTestCase Trait 组合测试断言中的$result-request/$result-response/$result-getBody()已改为$result-request()/$result-response()/$result-response()-getBody()app/Config/*、app/Views/errors/html/*、env、spark等项目空间文件已与官方骨架合并。完成以上全部项后你的项目即完成从 4.1.1 到 4.1.2 的平稳迁移。相关参考文档可继续查阅 升级总览 与各安装方式的详细升级章节。赞分享后端Web框架【免费下载链接】CodeIgniter4Open Source PHP Framework (originally from EllisLab)项目地址https://gitcode.com/gh_mirrors/co/CodeIgniter4点击查看免费下载相关推荐CodeIgniter 4.2.2 升级指南从 4.2.1 升级的破坏性变更与迁移清单CodeIgniter 4.2.2 升级指南从 4.2.1 升级的破坏性变更与迁移清单 本篇升级指南以 CodeIgniter4 官方文档 upgrade_4后端Web框架kafka-python 3.0 升级指南从 2.3 到 3.0 的破坏性变更与迁移实践kafka python 3.0 升级指南从 2.3 到 3.0 的破坏性变更与迁移实践 kafka python 3.0 是一次包含多项破坏性变更brea后端消息队列Svelte 4 迁移实战指南从 Svelte 3 到 4 的全部破坏性变更与升级要点Svelte 4 迁移实战指南从 Svelte 3 到 4 的全部破坏性变更与升级要点 本文基于 Svelte 仓库官方文档 Svelte 4 migrati前端Web框架编译器创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考