CI4中辅助函数必须手动加载,不再自动可用;所有辅助函数需显式调用helper()加载,自定义助手须放app/Helpers/目录且命名规范;old()和set_value()替代CI3的set_value()+clear_field_data();xss_clean()已移除,改用esc()按上下文编码;esc()仅适用于字符串,参数类型错误将导致异常。

CI4里辅助函数必须手动加载,不能自动可用
CI3默认加载了url、form、html等常用辅助函数,写完控制器就能直接用base_url()或form_open()。CI4彻底取消了这个机制——所有辅助函数都得显式加载,否则调用就报Call to undefined function base_url()。
实操建议:
- 在控制器顶部用
helper(['url', 'form', 'html'])一次性加载多个 - 在视图里也得加
helper('form')才能用form_open(),不能指望控制器加载后“透传”到视图 - 自定义辅助函数必须放在
app/Helpers/目录(不是system/helpers/),且文件名要小写+下划线,比如my_helper.php,函数名也得是小写+下划线风格 - CI4不支持CI3那种在
application/config/autoload.php里配置自动加载的方式,别往里面写$autoload['helper'] = ['url'],它完全无效
CI4的old()和set_value()替代了CI3的set_value() + clear_field_data()
CI3里常用$this->form_validation->set_value('email')回填,再配合clear_field_data()清空;CI4没有clear_field_data(),也不再绑定验证器对象。表单状态靠old()和set_value()协同管理,核心逻辑是:只在验证失败时回填,成功提交后重定向,自然清空。
实操建议:
- 表单字段统一用
old('email', '')而不是set_value('email', '')——前者能跨重定向保留上次POST数据,后者只读$_POST,重定向后就为空 - 控制器处理成功提交后,必须用
return redirect()->to('/form')->with('success', '提交成功');,不能直接return view('form'),否则刷新页面会重复提交 - 如果非要“清空但不重定向”,比如AJAX提交后清空字段,那就手动重置
$_SESSION['ci_flash_data']里对应键,但不推荐,破坏PRG模式
CI4移除了xss_clean(),别再调用它
CI3的xss_clean()辅助函数在CI4中已完全删除,代码里还留着调用就会直接报Call to undefined function xss_clean()。这不是加载问题,是函数本身不存在了。
实操建议:
- 删掉所有
xss_clean($input)调用,换成上下文编码:esc($input, 'html')用于HTML输出、esc($input, 'js')用于JS字符串、esc($input, 'url')用于URL属性 - 需要富文本过滤?集成
HTMLPurifier或league/commonmark,别试图用正则“清洗”HTML - 别把
esc()当万能解药——它只做输出编码,不替代输入验证和权限控制
CI4的esc()不是万能转义,参数类型错就失效
esc()是CI4新增的全局安全辅助函数,但它对参数类型敏感。传入数组、对象或null时不会报错,但返回结果可能不符合预期,比如esc(['<script>'], 'html')</script>返回空字符串,而不是逐项转义。
实操建议:
- 只对字符串类型调用
esc(),对数组先用array_map()包装:array_map(fn($v) => esc($v, 'html'), $arr) - 数据库查询参数一律走Query Builder或预处理语句,别用
esc()拼SQL - 模板里用
= esc($name, 'html') ?>,别省略第二个参数,esc($name)默认是'html',但显式写出更安全
helper(),实则堵住了CI3里大量隐式依赖和误用漏洞。最容易被忽略的是:所有旧项目迁移时,第一反应是“为什么函数找不到”,而不是检查是否漏加载——其实90%的报错都卡在这一步。


















