0

好的,我知道这是一种不好的做法,但是部分代码已经存在,我必须扩展它以运行带有一个参数的自定义函数。

因此,我们的页面存储在 db 中,当它们显示在我们的模板中时,我们当前在整个 html 页面上使用三个不同的带有 e 修饰符的 preg_replace 函数。

这似乎很慢,所以我想将其更改为仅使用一个 preg_replace 调用,并能够以 bbcode 方式提供带有 1 个参数的自定义函数:示例:

[FUNC:testfunc(测试字符串)]

所以,这就是我想出的......我不确定哪种方法更安全,preg_rplace 与 e 修改器,或 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() 函数传递给我的整个文章类以供使用。为每场比赛创建一个这样的匿名函数是否不好,性能方面?

4

1 回答 1

1

根据您执行此操作的次数,创建匿名函数可能很糟糕。

您始终可以使用方法调用进行回调,如下所示:

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

如果它们已经是对象属性,这允许您避免将任何参数传递给方法。

我倾向于使用 'e',因为它避免preg_replace_callback()preg_replace()在 eval 代码中正确转义任何模式匹配的陷阱,并避免了必须进行 eval 的开销(如果您使用的是像 APC 这样的操作码缓存,这意味着与在每次调用时编译的 eval 相比,编译为零)。它还使代码更易于阅读 - eval'd 代码总是看起来有点难看,因为您必须转义字符串。

也就是说,将 preg_replace() 与“e”一起使用并没有本质上的错误。

于 2011-10-19T03:42:31.090 回答