esperecyan / html-filter
这是一个简单的HTML过滤器,通过白名单来检查元素名和属性名。
v1.3.0
2020-01-25 02:48 UTC
Requires
- php: >=7.0
- esperecyan/url: ^5.0.0
- masterminds/html5: ^2.7.0
- psr/log: ^1.0.0
Requires (Dev)
- phpunit/phpunit: ^8.5.2
README
这是一个通过白名单检查元素名和属性的HTML过滤器。不执行HTML验证。
示例
<?php require_once 'vendor/autoload.php'; use esperecyan\webidl\TypeError; use esperecyan\url\URL; $filter = new \esperecyan\html_filter\Filter([ '*' => [ 'dir' => ['ltr', 'rtl', 'auto'], 'lang' => '/^[a-z]+(-[0-9a-z]+)*$/iu', 'title', 'translate' => ['', 'yes', 'no'], ], 'a' => ['href' => 'isURLWithNetworkScheme'], 'br', 'img' => ['alt', 'src' => 'isURLWithNetworkScheme'], 'p', 'time' => 'datetime', ]); $filter->setLogger(new class extends \Psr\Log\AbstractLogger { public function log($level, $message, array $context = []) { echo "$level: $message\n"; } }); var_dump($filter->filter(<<<'EOD' <script> window.alert('foobar'); </script> <a href="https://example.com/">例示用ドメイン</a> <a href="./file.html" title="テスト">相対URL</a> <bR data-clear=""> <p dir="ltr" lang='"invalid"'>アリス</p> <p dir="LtR" LanG='ja'>ボブ</p> EOD )); function isURLWithNetworkScheme(string $value): bool { try { $url = new URL($value); } catch (TypeError $exception) { return false; } return in_array($url->protocol, ['ftp:', 'http:', 'https:']); }
上面的示例输出如下。
notice: <script> タグの使用は許可されていません。
notice: <a> タグの href 属性値 "./file.html" は許可されていません。
notice: <br> タグの data-clear 属性の使用は許可されていません。
notice: <p> タグの lang 属性値 ""invalid"" は許可されていません。
notice: <p> タグの dir 属性値 "LtR" は許可されていません。
example.php:33:
string(179) "
window.alert('foobar');
<a href="https://example.com/">例示用ドメイン</a>
<a title="テスト">相対URL</a>
<br />
<p dir="ltr">アリス</p>
<p lang="ja">ボブ</p>"
安装
composer require esperecyan/html-filter
有关Composer安装方法,请参阅Composer的全局安装 - Qiita等。
要求
- PHP 7.0以上
用法
将白名单传递给esperecyan\html_filter\Filter构造函数的第一个参数。传递输入字符串给filter方法的第一个参数,可以得到HTML或XHTML格式的字符串。
此库只能处理作为body元素后代的片段HTML。无法正常处理包含xmlns属性的文档,以及具有http://www.w3.org/1999/xhtml
以外的命名空间(如svg元素、math元素)及其后代元素。同时,也会移除注释等。
白名单
注释始终是过滤对象。
选项
将关联数组传递给esperecyan\html_filter\Filter构造函数的第二个参数。如果为每个选项传递null,则忽略该指定。
日志记录
esperecyan\html_filter\Filter实现了PSR-3: Logger Interface的Psr\Log\LoggerAwareInterface。
Psr\Log\LogLevel::NOTICE的情况
注意
即使没有任何日志输出,也可能无法将输入作为XHTML处理。如果要在XHTML中嵌入,请通过esperecyan\html_filter\Filter->filter()输出。
<?php $filter = new \esperecyan\html_filter\Filter(['a', 'blockquote', 'code', 'h1', 'h2', 'pre']); $filter->setLogger(new class extends \Psr\Log\AbstractLogger { public function log($level, $message, array $context = []) use ($logged) { $logged = true; } }); $output = $filter->filter($input); $storage = $logged ? $output : $input;
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>XHTML文書</title> </head> <body> <?= (new \esperecyan\html_filter\Filter())->filter($storage) ?> </body> </html>
贡献
请通过Pull Request或Issue进行贡献。
语义化版本控制
本库采用语义化版本控制。公共API仅限于esperecyan\html_filter\Filter类的public方法。
许可
本库的许可为Mozilla Public License Version 2.0 (MPL-2.0)。