我正在创建一个论坛,我只希望在该论坛上显示img标签,并希望将所有其他标签安全地转义,但不是删除。除了从头开始创建函数以外,什么是完成此任务的最佳方法?
我曾尝试使用HTML Purifier,但它会剥离所有不需要的标签,并仅保留所需的标签。此外,我尝试了其他功能,例如strip_tags和htmlentities
以及在blaede({{ }}
)中使用的转义运算符,但是这些功能将剥离不需要的标签(我希望将其转义)或转义所有标签(我也不想这么做,因为我想保留<img>
和<br>
标签。我看到了其他类似的问题,但不幸的是,它们都没有真正帮助过我。
到目前为止,我正在使用的是:$post->content = Purifier::clean($request->content);
临时删除不需要的标签以防止XSS。
我希望在用户插入数据后将显示如下:
Hi all
<script>alert('hi all')</script>
<img src='sun.png'/>
现在显示以下内容
Hi all
hi all
<img src='sun.png'/>
UPDATE:
我的问题是not与被标记的问题重复。希望主持人将解决此问题。
您需要先用某些字符串占位符替换<img>
和<br>
标签,然后用htmlentities()
进行转义,然后再恢复原来的<img>
和<br>
标签。这是您的技巧:
$string = "Hi<br> all<script>alert('hi all')</script><img src='sun.png'/>";
// First we cleanup our string from possible pre-existing placeholders (like $$0, $$1 etc).
$string = preg_replace('~$$[0-9]+~', '', $string);
// Then we replace all <img> and <br> tags with such placeholders while
// storing them into $placeholders array.
$placeholders = [];
$i = 0;
$string = preg_replace_callback('~(<img[^>]*>(</img>)?|<br[^>]*>)~', function ($matches) use (&$placeholders, &$i) {
$key = '$$'.$i++;
$placeholders[$key] = $matches[0];
return $key;
}, $string);
// Our string no longer has <img> and <br> tags so we can safely escape
// the rest.
$string = htmlentities($string);
// Lastly we restore <img> and <br> tags by swapping them back instead of their respective placeholders.
foreach ($placeholders as $key => $placeholder) {
$string = str_replace($key, $placeholder, $string);
}
echo $string;
此代码将产生结果:
Hi<br> all<script>alert('hi all')</script><img src='sun.png'/>
此解决方案在很大程度上依赖于使用正则表达式,因此强烈建议您学习此主题,以防日后需要调整代码。