わかりました、これが悪い習慣であることはわかっていますが、コードの一部が既存のものであり、1 つの引数でカスタム関数を実行するように拡張する必要があります。
したがって、ページはデータベースに保存され、テンプレートに表示されるとき、現在、html ページ全体で e 修飾子を使用して 3 つの異なる preg_replace 関数を使用しています。
これは遅いように見えるので、1 つの preg_replace 呼び出しのみを使用するように変更し、bbcode の方法で 1 つの引数を持つカスタム関数を提供できるようにしたいと思います: 例:
[FUNC:testfunc(テスト文字列)]
それで、これが私が思いついたものです...どの方法がより安全かはわかりません.e修飾子を持つpreg_rplace、またはpreg_replace_callback:
<?php
$str = '
<h2>Title That should Not Be Affected</h2>
<p>[FUNC:linkbox(/somestuff/newpage.html)]</p>
<a href="[FUNC:getvar(url)]">[FUNC:getvar(title)]</a>
<p>Random Html THat should not be affected</p>
<p>[FUNC:linkbox(/somestuff/otherpage.html)]</p>
';
$str2 = preg_replace_callback('~\[FUNC:(.*?)\((.*?)\)\]~', 'callback_caller', $str);
$str = preg_replace('~\[FUNC:(.*?)\((.*?)\)\]~e', 'emodcaller("\\1", "\\2")', $str);
echo $str.'<br><br>'.$str2;
function callback_caller($args){
if(!isset($args[0], $args[1]))
return false;
$func = strip_tags($args[1]);
$param = isset($args[2]) ? strip_tags($args[2]) : '';
//Only allow calling of known functions
switch($func){
case 'linkbox':
return linkbox($param);
break;
case 'getvar':
return getvar($param);
break;
case 'default':
return '';
break;
}
}
function emodcaller($fun, $arg){
$arg = strip_tags($arg);
//Only allow calling of known functions
switch($fun){
case 'linkbox':
return linkbox($arg);
break;
case 'getvar':
return getvar($arg);
break;
case 'default':
return '';
break;
}
}
function linkbox($addy){
return 'Linkbox Called: '.$addy;
}
function getvar($arg) {
switch($arg){
case 'url':
return '/index.html';
break;
case 'title':
return 'This is a test title';
break;
}
}
?>
e 修飾子の使用について私が気に入っているのは、必要に応じて、次のように、必要に応じて php で直接関数呼び出しに別のパラメーターを追加できることです。
preg_replace('~\[FUNC:(.*?)\((.*?)\)\]~e', 'emodcaller("\\1", "\\2", $page->getid())', $str);
ある方法は他の方法よりも安全ですか? どちらも巨大なセキュリティ リスクですか? これらを実装する必要があります..
編集:次のような匿名関数を使用して、コールバック関数の追加パラメーターを渡すことができることがわかりました。
$content = preg_replace_callback(
'~(?:\<p\>)?\[FUNC:(.*?)\((.*?)\)\](?:\<\/p\>)?~',
function($matches) use ($article) {
return callback_caller($matches, $article);
},
$content);
これにより、callback_caller() 関数が記事クラス全体に渡され、使用できるようになります。試合ごとにこのような無名関数を作成するのは、パフォーマンス的に悪いですか?