TinyMCE富文本输入验证:经FILTER_SANITIZE_FULL_SPECIAL_CHARS处理后的校验方案
校验TinyMCE富文本输入的方案建议
首先,先聊聊你当前的校验流程:
- 先通过
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_FULL_SPECIAL_CHARS);对POST数据做转义,再进行字段校验,这个顺序是没问题的——毕竟校验要基于最终会存储/展示的内容,避免脏数据干扰校验逻辑。不过这里有个需要注意的点:FILTER_SANITIZE_FULL_SPECIAL_CHARS会把所有HTML特殊字符(比如<、>、&)转成HTML实体,这意味着如果你的TinyMCE本来允许用户使用合法的富文本标签(比如<p>、<b>、<ul>),这些标签也会被转义成<p>这种形式,最终展示的时候不会渲染成对应的格式,而是直接显示实体字符串。如果这不是你想要的效果,其实更推荐用专门的HTML净化库(比如HTMLPurifier),它可以精准允许你指定的安全标签和属性,同时过滤掉恶意的XSS代码,比单纯的全量转义更灵活。
接下来说说你拟定的正则表达式问题:
你的正则^[a-zA-Z0-9\s&amp;|&\.\!?\;\\-\<\>\/]*$存在几个小问题:
- 实体写法错误:比如你写的
&amp;实际匹配的是&这个字符串(也就是转义两次的&),但经过FILTER_SANITIZE_FULL_SPECIAL_CHARS处理后,原始的&只会被转成&,所以正则里应该直接写&来匹配转义后的&;同理,<转成<,正则里写<就好,不需要额外转义。 - 字符范围太窄:你担心遗漏数学公式符号是对的,这个正则只覆盖了极少量的符号,像
+、=、()、∑、π这些数学符号都没包含,甚至连常见的引号"、'也没允许。
如果坚持用当前的sanitize方式,我建议调整正则,放宽字符范围,同时支持Unicode符号:
// 调用自定义regex函数时使用这个正则,注意加上u修饰符支持Unicode $this->regex('/^[\p{L}\p{N}\s&;.,!?\-<>\/\p{Sm}\p{Sc}]*$/u', '富文本内容包含非法字符');
这个正则的含义:
\p{L}:匹配所有语言的字母(包括中文、日文等非英文)\p{N}:匹配所有数字\p{Sm}:匹配数学符号(比如+、-、×、÷、∑等)\p{Sc}:匹配货币符号(如果需要的话)- 剩下的
&;.,!?\-<>\/是你原来正则里的常见符号,保留下来
最后,关于你的自定义regex验证函数,逻辑是没问题的,但要记得在传入正则时加上合适的修饰符(比如上面的u),确保能正确处理Unicode字符。
额外提个小建议:除了字符合法性校验,最好再加个长度校验(比如限制富文本内容的最大字符数),避免存储过大的内容影响性能。
内容的提问来源于stack exchange,提问作者Matthew Barraud
相关产品推荐
相关产品推荐

