2011-10-18 12 views
0

これは悪い習慣ですが、コードの一部が存在していたため、カスタム関数を1つの引数で実行するようにコードを拡張する必要があります。preg_replace&preg_replace_callbackセキュリティの懸念

私たちのページはデータベースに保存されており、テンプレートに表示されているときは、HTMLページ全体で、現在e修飾子付きの3つの異なるpreg_replace関数を使用しています。

これは遅いようですので、私は一つだけにpreg_replace呼び出しを使用して、BBコードの形で1つの引数でカスタム関数を供給することができるようにそれを変更したいと思います。例:

[FUNC:testfunc(テスト文字列)]だから、

、これは私が、より安全である方法を確認してください電子の修飾子と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; 
    } 

} 
?> 

事I e修飾子を使用するのと同じように、別のパラメータを私が必要だった場合には、PHPで直接関数呼び出しを呼び出すことができます:

preg_replace('~\[FUNC:(.*?)\((.*?)\)\]~e', 'emodcaller("\\1", "\\2", $page->getid())', $str); 

1つの方法は他の方法より安全ですか?両方とも巨大なセキュリティリスクですか?私はこれらのいくつかの実装..を持っている必要が

編集:)(

$content = preg_replace_callback(
'~(?:\<p\>)?\[FUNC:(.*?)\((.*?)\)\](?:\<\/p\>)?~', 
function($matches) use ($article) { 
return callback_caller($matches, $article); 
}, 
$content); 

これはcallback_callerを渡す私の全体の機能:私はあなたのような匿名関数を使用してコールバック関数の追加パラメータを渡すことができることを考え出しました使用する記事クラス。 パフォーマンスが悪いすべての試合で、このような匿名関数を作成していますか?

答えて

1

これを実行している回数によっては、匿名関数の作成が悪い可能性があります。

あなたは常にこのようなコールバックメソッドの呼び出しを使用することができます:あなたは、彼らがすでにあるオブジェクトプロパティ場合、メソッドに引数を渡すことを避けることができます

$content = preg_replace_callback($rx, array($obj, 'method_name'), $content); 

を。あなたが使用している場合

は、私はそれが正しくeval'dコードに一致する任意のパターンをエスケープの落とし穴を回避し、(すべてでevalに持つのオーバーヘッドを回避するため、「E」とpreg_replace()preg_replace_callback()を好む傾向があるとAPCのようなオペコードキャッシュは、ゼロコンパイルと各コールでコンパイルされる評価があることを意味します)。また、コードを少し読みやすくしています - evalされたコードは、文字列をエスケープしなければならないので、ちょっとおかしなことになります。

しかし、「e」でpreg_replace()を使用することに本質的に間違っていることは何もありません。

+0

情報をいただき、ありがとうございました。私はクラスメソッドを使用することができませんでした。私はreplace_callbackメソッドに固執すると思います。 – Ben

関連する問題