TinyMCE编辑器插入含PHP变量的超链接被过滤失效如何解决
TinyMCE多语言链接问题解决方案
首先明确:你配置的protect规则无法实现需求是TinyMCE的机制导致的——该配置仅在编辑态临时保护代码不被编辑器清洗,提交输出时会自动把匹配到的受保护内容转成<!--mce:protected -->格式的注释占位符,不会原样保留PHP代码。不建议在编辑器内容中嵌入可执行PHP代码,不仅适配成本高,还会带来严重的webshell注入安全风险。
可按优先级选择以下落地方案:
方案1:存相对路径,渲染时自动补语言前缀(最推荐)
该方案无需修改编辑器逻辑,编辑人员操作成本最低,后期维护性最好:
- 编辑内容时,所有内部链接统一写不带语言前缀的根路径,例如直接插入
/products/product1即可,不需要额外加语言段 - 从数据库读取编辑器内容、渲染到页面前,用PHP批量替换内部链接,自动拼接当前语言前缀,参考代码:
// 读取存储的原始编辑器内容 $rawContent = $article['content']; // 仅替换开头为/的非外链内部链接,避免误替换http/https、mailto、tel等特殊链接 $parsedContent = preg_replace( '/href="\/(?!http|https|mailto|tel|ftp)([^"]+)"/i', 'href="/' . $lang . '/$1"', $rawContent ); // 输出替换后的内容即可 echo $parsedContent;
方案2:自定义占位符替换(精准度更高)
如果存在部分特殊根路径不需要拼接语言前缀的场景,可以用占位符方案避免误替换:
- 修改TinyMCE链接插件配置,插入内部链接时自动写入特殊占位符前缀,例如最终插入的链接格式为
href="{{lang}}/products/product1" - 渲染内容时,直接把占位符替换为当前语言值即可:
$parsedContent = str_replace('{{lang}}', $lang, $rawContent);
该方案不会出现误替换问题,兼容性更好。
方案3:还原mce保护标记(极不推荐)
如果坚持要在编辑器中直接写入PHP代码(仅建议仅你本人拥有编辑器权限时使用,否则存在严重安全漏洞),可以在接收编辑器提交内容、存入数据库前,把TinyMCE生成的保护标记解码还原为原始PHP代码,参考逻辑:
$submittedContent = $_POST['editor_content']; // 解码mce保护标记,还原原始代码 $parsedContent = preg_replace_callback('/<!--mce:protected (.*?)-->/', function($matches) { return urldecode($matches[1]); }, $submittedContent); // 再存入数据库
之前base标签不生效的原因
base标签仅对不带开头斜杠的相对路径生效,对/products/product1这类根路径无效,且必须填写带协议的完整URL才能正常工作。如果硬要用该方案,需要满足两个条件:
- 编辑插入内部链接时全部去掉开头斜杠,写为
products/product1格式 - base标签填写完整路径:
<base href="https://你的域名/<?php echo $lang; ?>/">
该方案会影响页面所有相对路径的资源、锚点跳转,很容易出现静态资源404问题,不推荐使用。
内容的提问来源于stack exchange,提问作者cheeseus
相关产品推荐
相关产品推荐

