PHP Использование функции шорткодов preg_replace_callback возвращает неправильный порядок элементов - PullRequest
0 голосов
/ 11 января 2019

Я определяю функцию, которая может обрабатывать шорткоды для пользователей с сообщениями, сделанными wisiwyg.

Использование функции на основе 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>

Что я могу сделать не так?

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Вот как бы я это сделал:

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);
}

Теперь, если вы вернетесь или откроете шорткод, это не изменится, потому что в любом случае оно будет сметено буфером.

0 голосов
/ 11 января 2019

Вы должны вернуть значение, а не отражать его. То, что вы видите, верно, в том смысле, что функция обратного вызова должна вычислять до того, как результат preg_replace_callback() будет возвращен вашей переменной.

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

Возвращение обеспечит агрегирование в остальные результаты из preg_replace_callback() и возврат в правильном порядке. Пример .

...