ホームページ  >  記事  >  バックエンド開発  >  PHP+Tidy - 完璧な XHTML エラー修正 + filtering_PHP チュートリアル

PHP+Tidy - 完璧な XHTML エラー修正 + filtering_PHP チュートリアル

WBOY
WBOYオリジナル
2016-07-21 15:55:50827ブラウズ

入力と出力
入力と出力は、多くの Web サイトの基本機能であると言えます。ユーザーがデータを入力すると、Web サイトは他の人が閲覧できるようにそのデータを出力します。

現在人気のブログを例に挙げます。ここでの入力と出力は、作成者が記事を編集し、他の人が読めるようにブログ記事ページを生成することです。
ここには問題があります。つまり、ユーザー入力は通常制御されておらず、セキュリティ上のリスクを伴う不正な形式やコードが含まれている可能性がありますが、Web サイトの最終出力は正しい HTML コードである必要があります。これには、エラー修正とユーザー入力のフィルタリングが必要です。

ユーザー入力を決して信用しないでください
あなたは次のように言うかもしれません: FCKeditor、TinyMCE など、今ではどこにでも WYSIWYG エディターが存在します...名前はたくさんあるかもしれません。確かに、これらはすべて標準の XHTML コードを自動的に生成できますが、Web 開発者であれば、「ユーザーが送信したデータを決して信頼しない」という言葉を聞いたことがあるはずです。

そのため、ユーザー入力データを修正およびフィルタリングする必要があります。

より良いエラー修正とフィルタリングが必要です
これまでのところ、私が遭遇した実装は非効率的で、理想的とは言えず、何らかの明らかな欠陥があります。よく知られた例を挙げると、WordPress は非常に広く使用されているブログ システムであり、操作が簡単で強力であり、豊富なプラグイン サポートを備えており、バックグラウンドで多数の巧妙なエラー修正およびフィルタリング コードをサポートしています。非常に頭の痛い問題、半角文字の強制置換、過度に保守的な置換ルールなどにより、コードを貼り付けて正しく表示するという要件を達成することが困難になります。

ところで、このブログは WordPress によってホストされており、これらの記事を正しく表示するために、オンラインでたくさん検索し、いくつかのプラグインを試しました。いくつかのフィルタリング ルールをコメントアウトしました。まともに見えることはほとんどありません -.-b

もちろん、私はそれ (WordPress) をあまり批判したくありません。ただ、もっと良くできることを示したいだけです。

Tidy とは何ですか?またどのように機能しますか?
Tidy ManPage の説明からの抜粋:

Tidy は、HTML、XHTML、および XML ファイルを読み取り、クリーンアップされたマークアップを書き込み、ほとんどのブラウザーで動作します。Tidy の一般的な用途は、プレーン HTML を W3C に準拠した HTML コードに変換することです。標準、HTML、XHTML、および 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+エラー修正とフィルタリングのきちんとした実装
上記の背景資料は非常に多く、非常に混乱しているように思えますが、問題を解決するための具体的なコードが最も直接的です。

1. 単純なエラー修正の実装

function HtmlFix($html)
{

if(!function_exists('tidy_repair_string'))
return $html
//tidy を使用して HTML コードを修復します

/ /repair
$str = tiny_repair_string($html,
array('output-xhtml'=>true),
tiny_parse_string($str,
=>true)、
turnVal = 0
$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( ,'show-body-only'=>TRUE
);

// 修復
$str = tiny_repair_string($html,$conf,'utf8')
// 解析ツリーを生成
$str = tiny_parse_string($) str,$conf,'utf8');

$s = '';

// 本体ノードを取得します
$body = @tidy_get_body($str);

// 各ノードをチェックし、出力
関数_dumpnode($ node、&$ s){

//ノード名を確認してください。 (未実装)
*** TODO ***
戻る; Foreach ($ node-& g t; ​​$ 名 = & gt; としての属性) {

/*
一部の DOM イベントをクリーンアップします (通常は先頭にあります)。
Onclick onmouseover など ...
または属性値に javascript: 単語が含まれている場合、
、href = "javascript:" などもクリアされます。
'.$name.'="'. Htmlescape ($ Value). '"'" ';

}}

//ノード
の下の子ノードを筆記的に確認します if ($node-> child) {

$ s. =' & Gt;

foreach($node->child as $child){
_dumpnode($child,$s) } // 子ノードが処理されますそしてラベルは閉じられます
$s.= 'name.'>'; }else{

$s .$s 。 .'>';
else
;待ってください
使用する ‐ ‐ ‐ ‐‐‐‐‐‐‐‐‐‐ - フィルター。
if($body->child){

foreach($body->child as $child)
_dumpnode($child,$s);
}else
return $s;
上記のコードのコメントを、コードと合わせてさらに詳しく見てみましょう。
記事内のリンクの自動識別など、より厳密なフィルタリングも簡単に拡張できます。


少し追加

以前に書いたウェブページで非常に長いテキストの改行問題を見たことがあれば、上記のコードの自動行折り返しを処理する関数が異なることに気づくかもしれません:

前回の紹介は HtmlEscapeInsertWbrs() だったので、上記の HtmlInsertWbrs() が使用されます。

ここで説明が必要です:
HtmlEscapeInsertWbrs() では、入力文字列が特殊文字でエスケープされていないこと、つまり、<>& などの htmlspecialchars() によって処理されていないことが必要です。関数内に特殊な処理があるためです。
Tidy で処理されたテキスト ノードを処理する場合、Tidy により <>& などの文字は対応する <>& で自動的にエスケープされるため、重複を避けるために特別な関数を使用する必要があります。この関数はHtmlInsertWbrs() は、名前からわかるように、 タグを挿入するだけで、追加の処理は行いません。

それでは、次のような質問があるかもしれません。

の途中に挿入されるなど、HTML タグの途中に挿入されると、それは iv> および これは、元の情報の表示に影響します。

はい、それは確かに新しい問題ですが、いくつかのテクニックを使用して効果的に解決できます:

Tidy によって取得されたテキスト ノードを扱っているため、HTML タグに遭遇することは不可能であるため、途中に挿入します。タグの状況は発生しません。
2 番目のケースでは、エスケープ文字はすべて &xxxxx; の形式になっており、1 のすべての & 記号の前に マークを挿入します (呼び出すときは 4 番目のパラメーターに注意してください)。 ;wbr> タグは、30 文字 (上記のコードで実際に呼び出される 2 番目のパラメーターを例として取り上げます) の後に挿入されますが、これはすでに xxxxx の長さよりも 2 大きくなっています。このように、上記 1 と 2 の 2 点により、エスケープ文字の途中に挿入されないようにすることができます。  htmlinsertwbrs()的php实现:

functionhtmlinsertwbrs($ 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 を返す;
}
...
わかりました、先にこれを書いてください。関連する資料は文中にあります。
次に再充電します。


http://www.bkjia.com/PHPjc/318191.html

tru​​ehttp://www.bkjia.com/PHPjc/318191.html技術記事入出力は、多くのウェブサイトの基本的な機能です。ユーザーはデータを送信し、ウェブサイトはデータを出力し、最近の流行のブログを例に挙げます。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。