从 3.x 升级到 4.x

CodeIgniter 4 是对框架的全面重写,与旧版本不向后兼容。 因此,更准确的说法是“转换”应用,而不是“升级”应用。 完成转换之后,从某个 CodeIgniter 4 版本升级到下一个版本将会非常简单。

“精简、高效、易用”的理念得以保留,但与 CodeIgniter 3 相比, 其实现方式存在大量差异。

这里并不存在一个 12 步的升级清单。相反,应当从一个全新的 CodeIgniter 4 项目文件夹开始, 按照你喜爱的方式安装和使用, 然后逐步转换并集成你的应用组件。 我们会在这里指出最重要的注意事项。

在升级项目时,我们总结了两个主要任务。首先是一些对所有项目都适用、 且必须处理的通用调整。其次是构成 CodeIgniter 的各个类, 它们包含了最重要的功能。这些类彼此独立运作, 因此需要逐个检查和处理。

在开始转换项目前,请务必阅读用户指南!

通用调整

下载

命名空间

  • CI4 基于 PHP 8.1+ 构建,框架中的所有内容都使用命名空间, 辅助函数和语言文件除外。

应用程序结构

重要

index.php 已不再位于项目根目录!它已被移动到 public 文件夹中, 以提升安全性并实现组件分离。

这意味着你需要将 Web 服务器配置为指向项目的 public 文件夹, 而不是项目根目录。

如果使用共享主机,请参阅 部署到共享主机服务

  • application 文件夹已重命名为 app,框架仍然包含 system 文件夹, 其含义与之前一致。

  • 框架现在提供了一个 public 文件夹,作为应用的文档根目录。

  • defined('BASEPATH') OR exit('No direct script access allowed'); 这一行已不再需要, 因为在标准配置下,public 文件夹之外的文件无法被直接访问。 同时,CI4 也不再定义 BASEPATH 常量,因此需要在所有文件中移除该行。

  • 还新增了 writable 文件夹,用于存放缓存数据、日志和 Session 数据。

  • app 文件夹在结构上与 CI3 的 application 非常相似, 但有一些名称变更,且部分子目录被移动到了 writable 文件夹中。

  • 不再存在嵌套的 application/core 文件夹, 因为 CI4 使用了不同的机制来扩展框架组件(见下文)。

路由

模型、视图与控制器

  • CodeIgniter 基于 MVC 概念,因此模型、视图和控制器的变更是最重要的部分之一。

  • 在 CodeIgniter 4 中,模型位于 app/Models,并且需要在 PHP 开始标签之后添加 namespace App\Models; 以及 use CodeIgniter\Model;。 最后一步是将 extends CI_Model 替换为 extends Model

  • CodeIgniter 4 的视图已移动到 app/Views。此外, 加载视图的语法需要从 $this->load->view('directory_name/file_name') 改为 echo view('directory_name/file_name');

  • CodeIgniter 4 的控制器需要移动到 app/Controllers。 然后在 PHP 开始标签后添加 namespace App\Controllers;。 最后,将 extends CI_Controller 替换为 extends BaseController

  • 有关更多信息,建议参考以下升级指南, 它们提供了将 CodeIgniter 4 中 MVC 类进行转换的分步说明:

核心类变更

  • 输入类
    • CI3 的 输入类 对应于 CI4 的 IncomingRequest

    • 由于历史原因,CI3 和 CI4 曾使用不正确的 HTTP 方法名称,如 “get”和“post”。自 v4.5.0 起,CI4 使用正确的 HTTP 方法名称, 如 “GET”和“POST”。

  • 输出类

类加载

  • 不再存在 CodeIgniter 的“超级对象”, 即框架组件不会再自动作为属性注入到控制器中。

  • 类会在需要时实例化,框架组件由 服务 进行管理。

  • 自动加载器 会自动处理 PSR-4 风格的类定位,适用于 App (即 app 文件夹) 和 CodeIgniter (即 system 文件夹)这两个顶级命名空间, 并支持 Composer 自动加载。

  • 你可以配置类加载方式,以支持任何你习惯的应用结构, 包括 “HMVC” 风格。

  • CI4 提供了 工厂, 可像 CI3 中的 $this->load 一样加载类并共享实例。

类库

  • 应用类库仍然可以放在 app/Libraries 中,但并非强制要求。

  • 不再使用 CI3 的 $this->load->library('x');, 而是可以按照命名空间的约定使用 $this->x = new \App\Libraries\X();。 或者,也可以使用 工厂$this->x = \CodeIgniter\Config\Factories::libraries('X');

辅助函数

钩子

  • CI3 的 钩子 已被 事件 所取代。

  • 不再使用 CI3 的 $hook['post_controller_constructor'], 而是使用 Events::on('post_controller_constructor', ['MyClass', 'MyFunction']);, 并使用命名空间 CodeIgniter\Events\Events;

  • 事件始终处于启用状态,并在全局范围内可用。

  • pre_controllerpost_controller 挂钩点已被移除, 请改用 控制器过滤器

  • display_overridecache_override 挂钩点已被移除, 因为相应的基础方法已不存在。

  • post_system 挂钩点被移动到最终渲染页面发送之前。

错误处理

  • CI4 中的错误处理行为略有变化。

    • 在 CI3 中,相关行为在 index.php 文件中设置:

      • error_reporting() 设置的错误级别的错误会被记录 (但是否写入日志文件取决于 log_threshold 设置)。

      • 错误级别为 E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR 的错误会停止框架执行, 不受 error_reporting() 设置的影响。

    • 在 CI4 中,相关行为在 app/Config/Boot/{environment}.php 文件中设置:

      • error_reporting() 设置的错误级别的错误会被记录 (但是否写入日志文件取决于 Config\Logger::$threshold 设置)。

      • 所有未被 error_reporting() 忽略的错误 都会停止框架执行。

扩展框架

  • 不再需要 core 文件夹来存放 MY_... 形式的 框架组件扩展或替换。

  • 不再需要在 libraries 文件夹中使用 MY_X 类 来扩展或替换 CI4 的组件。

  • 可以在任意位置创建这些类,并在 app/Config/Services.php 中添加相应的服务方法, 以加载你的组件来替代默认组件。

  • 详情请参阅 创建核心系统类

升级类库

  • 应用类仍然可以放在 app/Libraries 中,但并非强制要求。

  • 不再使用 CI3 的 $this->load->library('x');, 而是可以使用 $this->x = new \App\Libraries\X();, 遵循命名空间的约定来组织组件。 或者,也可以使用 工厂$this->x = \CodeIgniter\Config\Factories::libraries('X');

  • CodeIgniter 3 中的一些类在 4.x 中已不再存在。 对于这些类,需要寻找新的实现方式。 包括: 日历类FTP 类Javascript 类购物车类引用通告类XML-RPC 与 XML-RPC 服务器类, 以及 Zip 编码类

  • 其余在两个 CodeIgniter 版本中都存在的类, 可以通过一些调整完成升级。 最重要、最常用的类都提供了升级指南, 可通过简单的步骤和示例帮助你调整代码。