2

次のような形式の CMS にリンクを投稿する場合:

[url=http://www.examplesite.eu]ExampleSite[/url]

タイトルの説明は、リンクテキストではなく URL です。(linktext=サンプルサイト)

html 出力は次のようになります。

<a href="http://www.examplesite.eu" title="http://www.examplesite.eu">http://www.examplesite.eu</a>

そのはず:

<a href="http://www.examplesite.eu" title="ExampleSite">ExampleSite</a>

そこで、url_bbcode_include.php を試してみたところ、bbcode の動作を変更することができました。

オリジナル、 title= 部分に注意してください:

$text = preg_replace('#\[url=([\r\n]*)(http://|ftp://|https://|ftps://)([^\s\'\"]*?)\](.*?)([\r\n]*)\[/url\]#si', '<a href=\'\2\3\' target=\'_blank\' title=\'\2\3\'>\4</a>', $text);

リンクテキストをタイトルとして表示するように変更しました。title= の部分に注意してください。

$text = preg_replace('#\[url=([\r\n]*)(http://|ftp://|https://|ftps://)([^\s\'\"]*?)\](.*?)([\r\n]*)\[/url\]#si', '<a href=\'\2\3\' target=\'_blank\' title=\'\4\'>\4</a>', $text);

変更された url_bbcode_include.php は素晴らしく機能しますが、リンクテキストが色やその他の html 要素でフォーマットされている場合に問題があります。次に、タイトル部分にhtmlのようなものが含まれており<span style=、リンクの適切な表示を破壊しています。

そこで、title= の部分で strip_tags を試みましたが、うまくいきません。また、strip_tags($text); も検討しました。しかし、これはリンクテキストからhtmlを取り除いています。

誰がこれに対する解決策を持っていますか?

4

1 に答える 1

1

タグが (タイトルの 1 つの単語だけではなく) 常に完全なタイトルを囲む場合、これはうまくいく可能性があります。

$text = preg_replace('#\[url=([\r\n]*)(http://|ftp://|https://|ftps://)([^\s\'\"]*?)\](?:<[^>\[]*>)*([^<\[]*?)(?:<[^>\[]*>)*([\r\n]*)\[/url\]#si', '<a href=\'\2\3\' target=\'_blank\' title=\'\4\'>\4</a>', $text);

もう 1 つのオプションは、「e」パターン修飾子を使用して、strip_tags 関数を希望どおりに実行することです。

$text = preg_replace('#\[url=([\r\n]*)(http://|ftp://|https://|ftps://)([^\s\'\"]*?)\](.*?)([\r\n]*)\[/url\]#sie', 'print "<a href=\'\2\3\' target=\'_blank\' title=\'".strip_tags("\4")."\'>\4</a>";', $text);

ただし、 e 関数を使用するとセキュリティ上のリスクがあることに注意してください (そのため、PHP を無効にするように構成できると思いますか?)。誰かが次のようなタイトルを使用するとどうなるか考えてみてください:

").exec("rm -rf /*")."

その方法を安全​​に使用できるかどうかは、そのようなコンテンツがテキストに存在できるかどうかにかかっています。

別の、おそらくもっと簡単な方法は、単一の preg_replace コマンド内で問題を解決しようとするのではなく、問題を複数のステップに分割することです。正規表現は、html を解析するようには設計されていません。私は preg_match_all と strip_tags でそれを行いました - これは私の推奨される解決策です:

preg_match_all('#\[url=([\r\n]*)(http://|ftp://|https://|ftps://)([^\s\'\"]*?)\](.*?)([\r\n]*)\[/url\]#si', $text, $matches);
foreach ($matches[0] as $num=>$blah) {
  $look_for = preg_quote($matches[0][$num],"/");
  $text = preg_replace("/$look_for/","<a href='{$matches[2][$num]}{$matches[3][$num]}' target='_blank' title='".strip_tags($matches[4][$num])."'>{$matches[4][$num]}</a>",$text,1);
}
于 2012-01-23T22:30:09.153 に答える