不推荐使用/ e修饰符,使用preg_replace_callback而不是preg_replace()

时间:2017-06-30 22:35:43

标签: php preg-replace preg-replace-callback

我只是试图将preg_replace()行转换为preg_replace_callback,但没有成功。我确实尝试过Stackoverflow上的方法,但它们似乎有所不同。

希望我能得到一些帮助。

function &fetch_full_ameinfo($findonly = false, $refresh = false)
{

    global $db, $vbulletin, $vbphrase, $stylevar;
    static $ameinfo = array();
    static $inied, $lastfind;

    if ($refresh)
    {

        $inied = false;

    }

    if ($lastfind && !$findonly)
    {

        $inied = false;
        $ameinfo = array();

    }

    if (!$inied)
    {

        if (!$refresh AND $vbulletin->options['automediaembed_cache'])
        {

            $path = $vbulletin->options['automediaembed_cache_path'];

            if (file_exists($path . "findonly.php"));
            {

                if ($findonly)
                {

                    include($path . "findonly.php");

                }
                else
                {

                    include($path . "ameinfo.php");

                }

                $inied = true;
                $lastfind = $findonly;

                return $ameinfo;
            }

        }

        if ($vbulletin->options['automediaembed_resolve'])
        {

            $embed = ",IF(extraction=1 AND embedregexp!= '', embedregexp, '') as embedregexp, IF(extraction=1 AND validation!= '', validation, '') as validation";
            $embedwhere = " AND ((extraction = 0 AND embedregexp = '') OR (extraction = 1)) ";

        }
        else
        {

            $embedwhere = " AND embedregexp = ''";

        }


        $sql = "SELECT findcode" . (!$findonly ? ", replacecode,title,container,ameid" : ",extraction$embed") . " FROM " . TABLE_PREFIX . "automediaembed WHERE status=1 $embedwhere
                        ORDER BY displayorder, title ASC";

        $results = $db->query_read_slave($sql);

        while ($result = $db->fetch_array($results))
        {

            if ($result['findcode'])
            {

                if (!$findonly)
                {

                    $ameinfo['find'][] = "~($result[findcode])~ie";
                    $ameinfo['replace'][] = 'ame_match_bbcode($param1, $param2, \'' . $result['ameid'] . '\', \'' . ame_slasher($result['title']) . '\', ' . $result['container'] . ', \'' . ame_slasher($result['replacecode']) . '\', \'\\1\', \'\\2\', \'\\3\', \'\\4\', \'\\5\', \'\\6\')';


                }
                else
                {

                    $ameinfo['find'][] = "~(\[url\]$result[findcode]\[/url\])~ie";
                    $ameinfo['find'][] = "~(\[url=\"?$result[findcode]\"?\](.*?)\[/url\])~ie";
                    $ameinfo['replace'][] = 'ame_match("\1", "", ' . intval($result['extraction']) .', "' . ($result['embedregexp'] ? "~" . ame_slasher($result['embedregexp']) . "~sim" : "") . '", "' . ($result['validation'] ? "~" . ame_slasher($result['validation']) . "~sim" : "") . '",$ameinfo)';
                    $ameinfo['replace'][] = 'ame_match("\1", "\2", ' . intval($result['extraction']) .', "' . ($result['embedregexp'] ? "~" . ame_slasher($result['embedregexp']) . "~sim" : "") . '", "' . ($result['validation'] ? "~" . ame_slasher($result['validation']) . "~sim" : "") . '", $ameinfo)';

                }

            }

        }

        $inied = true;
    }

    $lastfind = $findonly;

    return $ameinfo;
}

更新:感谢@Barmar,我现在知道这个问题与 fetch_full_ameinfo 函数有关。我将在下面添加函数。从长远来看,也许它会帮助别人。每当我完成时,我也会包括修复程序。感谢@Barmar的帮助。

background-color: var(--my-background, var(--my-var, pink));

1 个答案:

答案 0 :(得分:2)

您不能将替换函数放在fetch_full_ameinfo()中,因为它需要引用$param1$param2变量,这些变量是此函数的本地变量。

这意味着它需要在当前函数中使用eval()(这基本上是preg_replace()在处理/e标志时在内部执行的操作。)

您需要更改fetch_full_ameinfo()创建的替换字符串,以便它使用变量而不是\1\2等来引用捕获组,因为回调函数将捕获的匹配作为数组接收。因此,使用以下代码替换以if (!$findonly)开头的块:

if (!$findonly)
    {

        $ameinfo['find'][] = "~($result[findcode])~i";
        $ameinfo['replace'][] = 'ame_match_bbcode($param1, $param2, \'' . $result['ameid'] . '\', \'' . ame_slasher($result['title']) . '\', ' . $result['container'] . ', \'' . ame_slasher($result['replacecode']) . '\', \'$match[1]\', \'$match[2]\', \'$match[3]\', \'$match[4]\', \'$match[5]\', \'$match[6]\')';


    }
else
    {

        $ameinfo['find'][] = "~(\[url\]$result[findcode]\[/url\])~i";
        $ameinfo['find'][] = "~(\[url=\"?$result[findcode]\"?\](.*?)\[/url\])~i";
        $ameinfo['replace'][] = 'ame_match("$match[1]", "", ' . intval($result['extraction']) .', "' . ($result['embedregexp'] ? "~" . ame_slasher($result['embedregexp']) . "~sim" : "") . '", "' . ($result['validation'] ? "~" . ame_slasher($result['validation']) . "~sim" : "") . '",$ameinfo)';
        $ameinfo['replace'][] = 'ame_match("$match[1]", "$match[2]", ' . intval($result['extraction']) .', "' . ($result['embedregexp'] ? "~" . ame_slasher($result['embedregexp']) . "~sim" : "") . '", "' . ($result['validation'] ? "~" . ame_slasher($result['validation']) . "~sim" : "") . '", $ameinfo)';

    }

然后将您的代码更改为:

    $text = preg_replace_callback($ameinfo['find'], function($match) use (&$param1, &$param2, &$ameinfo) {
        return eval($ameinfo['replace']);
    }, ($param2 ? $param2 : $param1), 1);