【问题标题】:PHP Using preg_replace_callback shortcodes function returns wrong elements orderPHP 使用 preg_replace_callback 短代码函数返回错误的元素顺序
【发布时间】:2019-06-06 15:15:51
【问题描述】:

我正在定义一个函数,它可以为用户所见即所得的帖子处理短代码。

使用基于 preg_replace_callback 的函数效果很好,但返回的替换值在初始字符串之前打印

这是处理函数

function shortcodify($string){
    return preg_replace_callback('#\[\[(.*?)\]\]#', function($matches){
        $parts = explode(':',$matches[1]);
        $fnName = array_shift($parts);
        if(function_exists($fnName)){
            return call_user_func_array($fnName,$parts);
        } else {
            return $matches[0];
        }
    },$string);
}

这是替换短代码的功能

function slider($tag){
    //search $tag in DB
    echo '<div>...'.$sliderContentFromDB.'...</div>';
}

用法:

$postContent = "<h1>Super Slider</h1> [[slider:super-slider]] <p>Slider Description</p>";
shortcodify($postContent);

预期结果是:

<h1>Super Slider</h1>
<div>...super slider content...</div>
<p>Slider Description</p>

实际结果是:

<div>...super slider content...</div>
<h1>Super Slider</h1>
<p>Slider Description</p>

我做错了什么?

【问题讨论】:

  • 你必须记住内容是一个短代码的集合(把它想象成一个数组)所以在你遍历数组之前你不会输出完整的内容,所以当你从循环中回显时(来自循环调用的slider)输出首先出来。
  • 确实更有意义
  • 一个技巧是使用 ob_start()ob_get_clean() 然后你可以从短代码中回显,但仍然在回调中捕获输出

标签: php regex function callback preg-replace


【解决方案1】:

我会这样做:

function shortcodify($string){
    return preg_replace_callback('#\[\[(.*?)\]\]#', function($matches){
        //start output buffering
        ob_start();
        $parts = explode(':',$matches[1]);
        $fnName = array_shift($parts);

        //echo values in case they return instead of echo
        if(function_exists($fnName)){
            echo call_user_func_array($fnName,$parts);
        } else {
            echo $matches[0];
        }
        //return contents of buffer
        return ob_get_clean();
    },$string);
}

现在,如果您从短代码返回或回显,则没有区别,因为在任何一种情况下,它都会被缓冲区清除。

【讨论】:

    【解决方案2】:

    您应该返回该值而不是回显它。您看到的是正确的,因为回调函数应该在 preg_replace_callback() 结果返回到您的变量之前进行评估。

    function slider($tag){
        //search $tag in DB
        return '<div>...'.$sliderContentFromDB.'...</div>';
    }
    

    返回将确保它将来自preg_replace_callback() 的结果聚合到其余结果中,并以正确的顺序返回。 Example.

    【讨论】:

    • 附带说明:添加\n 将生成格式良好的呈现HTML(源),而不是全部放在一行上; 只是说
    • @FunkFortyNiner 你是对的,这样做只是为了演示目的
    • 是的,我认识罗比 :)
    • 你呢?哈哈! :-D
    • 我想——虽然让我发笑
    猜你喜欢
    • 2017-05-06
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 2015-03-04
    • 2013-04-07
    • 2023-03-13
    • 1970-01-01
    相关资源
    最近更新 更多