CodeIgniter集成HTMLPurifier报htmlpurifier()未定义错误排查
CodeIgniter集成HTMLPurifier未定义函数报错修复方案
核心问题汇总
现有代码存在6个直接触发报错的问题:
- 辅助函数语法错误:全局函数不能加
public访问修饰符,public仅用于类的成员方法,写在全局函数上会直接触发语法错误 - 函数名不匹配:定义的净化函数名为
html_purify(中间带下划线),调用时写的是htmlpurifier(无下划线),名称不一致 - 加载逻辑错误:CodeIgniter的辅助函数(Helper)不支持通过命名空间直接调用,
\App\Helpers\htmlpurifier()这种调用方式不符合框架规则,且框架默认不会自动加载自定义的辅助文件 - 类文件引入路径错误:代码里写的
APPPATH."app/ThirdParty/..."存在路径重复,APPPATH常量本身已经指向项目的app目录,多拼接一层app会导致HTMLPurifier类文件找不到 - HTMLPurifier配置代码错误:
addAttribute方法单次仅支持添加一个属性,一次传入3个参数会触发方法调用错误 - 业务逻辑错误:调用净化函数前没有正确获取表单提交的
content字段值,传参逻辑混乱
正确配置与调用步骤
1. 修正辅助文件代码
打开App/Helpers/htmlpurifier_helper.php,替换为以下修正后的代码:
defined('BASEPATH') or exit('No direct script access allowed'); if (!function_exists('html_purify')) { // 全局函数不能加public修饰符 function html_purify($dirty_html, $config = false) { $clean_html = ''; if (is_array($dirty_html)) { foreach ($dirty_html as $key => $val) { $clean_html[$key] = html_purify($val, $config); } return $clean_html; } $ci = &get_instance(); switch ($config) { case 'comment': $purifier_config = \HTMLPurifier_Config::createDefault(); $purifier_config->set('Core.Encoding', $ci->config->item('charset')); $purifier_config->set('HTML.Allowed', 'p,a[href|title],abbr[title],acronym[title],b,strong,blockquote[cite],code,em,i,strike'); $purifier_config->set('AutoFormat.AutoParagraph', true); $purifier_config->set('AutoFormat.Linkify', true); $purifier_config->set('AutoFormat.RemoveEmpty', true); break; case false: $purifier_config = \HTMLPurifier_Config::createDefault(); $purifier_config->set('Core.Encoding', 'utf-8'); $purifier_config->set("AutoFormat.AutoParagraph", false); $purifier_config->set("Core.NormalizeNewlines", true); $purifier_config->set('HTML.Allowed', 'iframe[src|title|frameborder|allowfullscreen|class|width|height|loading],p,b,strong,a[href|title],abbr[title],blockquote[cite],code,pre[class],em,i,strike,u,s,sub,sup,ol,ul,li,hr,img[title|alt|src|class|style],h1,h2,h3,h4,h5,h6,object[width|height|data],param[name|value],embed[src|type|allowscriptaccess|width|height],br,*[style]'); $purifier_config->set('CSS.AllowedProperties', 'font,font-size,font-weight,font-style,font-family,text-decoration,margin-left,margin-right,float,color,background-color,text-align,width,max-width'); $purifier_config->set('HTML.MaxImgLength', NULL); $purifier_config->set('CSS.MaxImgLength', NULL); $purifier_config->set('HTML.SafeObject', true); $purifier_config->set('HTML.SafeEmbed', true); $purifier_config->set('Output.FlashCompat', true); $purifier_config->set('AutoFormat.RemoveEmpty', true); $purifier_config->set('AutoFormat.RemoveEmpty.RemoveNbsp', true); $purifier_config->set('HTML.SafeIframe', true); $purifier_config->set('URI.SafeIframeRegexp', '%^//(www.youtube(?:-nocookie)?.com/embed/|player.vimeo.com/video/)%'); $def = $purifier_config->getHTMLDefinition(true); // addAttribute单次仅添加一个属性 $def->addAttribute('iframe','allowfullscreen', 'Bool'); $def->addAttribute('iframe','loading', 'Text'); break; default: show_error('The HTMLPurifier configuration labeled "'.htmlspecialchars($config, ENT_QUOTES, $ci->config->item('charset')).'" could not be found.'); } // 去掉重复的app路径拼接 require_once(APPPATH."ThirdParty/htmlpurifier/HTMLPurifier.auto.php"); require_once(APPPATH."ThirdParty/htmlpurifier/HTMLPurifier.func.php"); $purifier = new \HTMLPurifier($purifier_config); $clean_html = $purifier->purify($dirty_html); return $clean_html; } } /* End of htmlpurifier_helper.php */ /* Location: ./app/helpers/htmlpurifier_helper.php */
注意:确认HTMLPurifier源码存放路径为
app/ThirdParty/htmlpurifier/,保证HTMLPurifier.auto.php文件在该目录下,不要多套层级。
2. 加载辅助文件
CodeIgniter加载自定义辅助文件有两种可选方式,二选一即可:
- 全局自动加载:打开
app/Config/Autoload.php,在$helpers数组中添加'htmlpurifier',配置后项目所有位置都可以直接调用净化函数 - 控制器内临时加载:在需要使用净化功能的控制器方法中,调用函数前加入
helper('htmlpurifier');即可完成加载
加载规则:辅助文件加载只需要传文件名去掉
_helper.php后缀的部分,比如htmlpurifier_helper.php就传htmlpurifier,框架会自动到Helpers目录下匹配对应文件。
3. 修正控制器调用逻辑
删掉原来错误的命名空间调用代码,替换为正确的表单取值、净化逻辑:
// 表单验证规则 $val->setRule('content', translation("content"), 'required'); // 执行验证 if (!$val->withRequest($this->request)->run()) { // 这里写验证不通过的业务逻辑,比如返回错误提示、跳转回表单页 } // 获取验证通过的表单提交内容 $dirty_content = $this->request->getPost('content'); // 直接调用全局函数做内容净化,不需要加任何命名空间前缀 $clean_content = html_purify($dirty_content, 'comment');
避坑提醒
- 辅助函数文件名必须全小写,后缀固定为
_helper.php,否则框架无法识别加载 - 辅助函数都是全局函数,加载完成后直接写函数名调用即可,不要加命名空间前缀
- 如果开启了框架缓存,修改完代码后清空
writable/cache目录下的所有缓存文件,避免旧缓存干扰加载
内容的提问来源于stack exchange,提问作者DLK
相关产品推荐
相关产品推荐

