ホームページ  >  記事  >  バックエンド開発  >  xhtml PHP+Tidy - 完璧な XHTML エラー修正 + フィルタリング

xhtml PHP+Tidy - 完璧な XHTML エラー修正 + フィルタリング

WBOY
WBOYオリジナル
2016-07-29 08:36:55895ブラウズ

入力と出力
入力と出力は、多くの Web サイトの基本機能であると言えます。ユーザーがデータを入力すると、Web サイトは他の人が閲覧できるようにそのデータを出力します。
現在人気のブログを例に挙げます。ここでの入力と出力は、作成者が記事を編集し、他の人が読めるようにブログ記事ページを生成することです。
ここには問題があります。つまり、ユーザー入力は通常制御されておらず、セキュリティ上のリスクを伴う不正な形式やコードが含まれている可能性がありますが、Web サイトの最終出力は正しい HTML コードである必要があります。これには、エラー修正とユーザー入力のフィルタリングが必要です。
ユーザー入力を決して信用しない
あなたは次のように言うかもしれません: 今ではどこにでも WYSIWYG エディター (WYSIWYG) があり、FCKeditor、TinyMCE... たくさん名前を挙げることができます。確かに、これらはすべて標準の XHTML コードを自動的に生成できますが、Web 開発者であれば、「ユーザーが送信したデータを決して信頼しない」という言葉を聞いたことがあるはずです。
そのため、ユーザー入力データを修正およびフィルタリングする必要があります。
より良いエラー修正とフィルタリングが必要です
これまでのところ、私が遭遇した実装は非効率的で、理想的とは言えず、何らかの明らかな欠陥があります。よく知られた例を挙げると、WordPress は非常に広く使用されているブログ システムであり、操作が簡単で強力であり、豊富なプラグイン サポートを備えており、バックグラウンドで多数の巧妙なエラー修正およびフィルタリング コードをサポートしています。非常に頭の痛い問題、半角文字の強制置換、過度に保守的な置換ルールなどにより、コードを貼り付けて正しく表示するという要件を達成することが困難になります。
ちなみに、このブログは WordPress によってホストされており、これらの記事を正しく表示するために、ネットでいろいろ検索し、プラグインをいくつか試してみました。いくつかのフィルタリング ルールをコメントアウトして、より適切に表示できるようにしました -.-b
もちろん、私はそれ (WordPress) をあまり批判したくありません。ただ、もっと良くできることを示したいだけです。
Tidy とは何ですか?またその仕組みは何ですか?
Tidy ManPage の説明からの抜粋:
Tidy は、HTML、XHTML、および XML ファイルを読み取り、ほとんどのブラウザーでクリーンアップされたマークアップを書き込みます。これは、HTML、XHTML をサポートする、プレーン HTML を W3C 標準 HTML コードに変換することです。 XML。 Tidy は、Tidy の強力な機能を他のアプリケーションで簡単に使用できるようにするライブラリ TidyLib を提供します。幸いなことに、PHP には使用できる対応する Tidy モジュールがあります。
兄弟、なぜまた PHP なのですか?
えっと、この質問は...恥ずかしいのですが、私は PHP について少ししか知りません -.-v
しかし幸いなことに、ここで私が話していることは、少なくともそこには純粋なコードではありません。分析プロセスであるため、コードを投稿するよりもこれらを共有する方がはるかに役立ちます。
PHP で Tidy を使用する
PHP で Tidy を使用するには、Tidy モジュールをインストールする必要があります。これは、PHP 拡張機能 tiny.so をロードすることを意味します。具体的なプロセスは省略されており、純粋に物理的な作業です。最後に、phpinfo()で「Tidy support有効」と表示されていればOKです。
このモジュールのサポートにより、Tidy が提供するほぼすべての機能が PHP で使用できるようになります。一般的に使用される HTML のクリーニングは非常に簡単で、ドキュメントの解析ツリーを生成し、クライアント上で DOM を操作するように HTML の各ノードを操作することもできます。以下に具体的なコードの手順を示します。また、公式の PHP マニュアルも参照してください。
エラー修正とフィルタリングの PHP+Tidy 実装
上記の背景資料は非常に多く、非常に混乱しているように思えますが、問題を解決するための具体的なコードが最も直接的です。
1. 単純なエラー修正の実装
function HtmlFix($html)
{
if(!function_exists('tidy_repair_string'))
return $html;
//tidy を使用して HTML コードを修復します
//repair
$str = tiny_repair_string ($html,
array('output-xhtml'=>true)、 tidy_repair_string($html,
array('output-xhtml'=&g t;true
return $s
}
foreach($nodes as $ n){
$s.= $n->value;
}
return $s;
上記のコードは、標準化されていない可能性のある XHTML コードをクリーンアップして修正するためのものです (入力と出力は両方とも UTF-8 でエンコードされます)。実装コードは以下のフィルタリング機能と連携させるため、できるだけ詳細に記述したため、あまり合理化されたものではありません。
2. 高度な実装: エラー修正 + フィルタリング
機能:
XHTML エラー修正、標準 XHTML コードを出力します。
安全でないコードをフィルタリングしますが、コンテンツの表示には影響しません。スタイル/JavaScript 内の安全でないコードのみをクリアします。
ブラウザ互換の自動行折り返しを実現するには、非常に長い文字列に タグを挿入します。関連記事については、Web ページ上の非常に長いテキストの改行の問題を参照してください。
function HtmlFixSafe($html)
{
if(!function_exists('tidy_repair_string'))
return $html;
// HTML コードを修復するために Tidy を使用します
// パラメータ設定を整理します
$conf = array(
' Output- xhtml'=>true
、'drop-empty-paras'=>FALSE 、'join-classes'=>TRUE
、'show-body-only'=>TRUE
/ /repair
$str = tiny_repair_string($html,$conf,'utf8');
//解析ツリーを生成する
$str = tiny_parse_string($str,$conf,'utf8')
//取得ボディノード
$body = @tidy_get_body($str);
//関数 _dumpnode、各ノードを確認し、フィルターして出力
function _dumpnode($node,&$s){
// ノード名を表示します (if 場合) < script>} if($ node-> tidy_nodetype_text){
// insert< wbr> ');
// 自動リンク ??? *** TODO ***
return ;
// テキストノードでない場合は、ラベルとその属性を処理します
$s.= '<' .$node->name;
// 各属性を確認する
if($node->attribute ) {Re Foreach ($ Node-& GT; Attribute as $ name = & gt; $ value) {
/*
いくつかの DOM イベントをクリーンアップします (通常は最初に




javascript: 単語 (href="javascript:" など) もクリアされます) ; }
}
// 以下の子ノードを再帰的にチェックします。このノードif($ node-&gt; child){
$ s。= '&gt;';Else {*/*
にはサブノードがなく、ラベルは閉じられています (実際、空のノードを直接削除することも検討できます)
*/
IF ($ node-& gt; type == tiDYETYPE_START)
$ s. = '>/'.$node->name.'>' ''''''''''''''''''''アウトとインは私の'' ''- out- out- out through through off off./& gt; を閉じて直接待機します
*/
$ s. = '/& Gt;';}}}}
// 関数が終了を定義します
//上記の関数を使用して、body ノードのフィルタリングを開始します。
if($body->child){
foreach($body->child as $child)
}else
return '';上記のコードのコメントをさらに詳しく説明します。コードと併せて動作原理を見てみましょう。
記事内のリンクの自動識別など、より厳密なフィルタリングも簡単に拡張できます。
少し追加
私が以前に書いたウェブページで非常に長いテキストの改行の問題を見たことがあれば、上記のコードで自動行折り返しを処理する関数が異なることに気づくかもしれません:
前回の紹介は HtmlEscapeInsertWbrs() でした。 、上記のものは HtmlInsertWbrs () を使用しています。
説明は次のとおりです:
HtmlEscapeInsertWbrs() では、入力文字列が特殊文字でエスケープされていないこと、つまり、<>& などの htmlspecialchars() によって処理されていないことが必要です。関数内に特殊な処理があるためです。
Tidy で処理されたテキスト ノードを処理する場合、Tidy により <>& などの文字は対応する <>& で自動的にエスケープされるため、重複を避けるために特別な関数を使用する必要があります。この関数はHtmlInsertWbrs() は、名前からわかるように、 タグを挿入するだけで、追加の処理は行いません。
それでは、次のような質問があるかもしれません。
が HTML タグの途中に挿入されると、 になります。 ;wbr>iv> および これは、元の情報の表示に影響します。
はい、これは確かに新しい問題ですが、いくつかのテクニックを使用して効果的に解決できます。
Tidy によって取得されたテキスト ノードを扱っているため、HTML タグに遭遇することは不可能であるため、途中に < を挿入します。 wbr> の状況には遭遇しません。
2 番目のケースでは、エスケープ文字はすべて &xxxxx; の形式になっており、1 のすべての & 記号の前に マークを挿入します (呼び出すときは 4 番目のパラメーターに注意してください)。 ;wbr> タグは、30 文字 (上記のコードで実際に呼び出される 2 番目のパラメーターを例として取り上げます) の後に挿入されますが、これはすでに xxxxx の長さよりも 2 大きくなっています。このように、上記 1 と 2 の 2 点により、エスケープ文字の途中に挿入されないようにすることができます。 
次に出てくるHtmlInsertWbrs()のPHP实现:
function HtmlInsertWbrs($str, $n=10,
$chars_to_break_after='',$chars_to_break_before='')
{
$out = '';
$strpos = 0;
$spc = 0;
$len = mb_strlen($str,'UTF-8');
for ($i = 1; $i < $len; ++$i) {
$prev_char = mb_substr($str,$i-1,1,'UTF-8');
$next_char = mb_substr($str,$i,1,'UTF-8');
if (_u_IsSpace($next_char)) {
$spc = $i;
} else {
if ($i - $spc == $n
mb_strpos( $chars_to_break_after,
$prev_char,0,'UTF-8')
!== FALSE
mb_strpos( $chars_to_break_before,
$next_char,0 ,'UTF-8')
!== FALSE
) {
$out .= mb_substr($str,$strpos,
$i-$strpos 、'UTF-8')
。 '';
$strpos = $i;
$spc = $i;
}
}
}
$out .= mb_substr($str,$strpos,$len-$strpos,'UTF-8');
$out を返す;
}
...
わかりました、先にこれを書いてください。関連する資料は文中にあります。
次に再充電します。

以上は、xhtml PHP+Tidy-完璧な XHTML セキュリティ + フィルタリングであり、xhtml に関する内容が含まれており、PHP 教則に関心のある友人の助けになることを望みます。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。