PHP Использование функции коротких кодов preg_replace_callback возвращает неправильный порядок элементов

Я определяю функцию, которая может обрабатывать короткие коды для сообщений, публикуемых 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>

Что я делаю не так?

Вы должны помнить, что контент - это набор шорткодов (думайте о нем как о массиве), поэтому вы не выводите полный контент до тех пор, пока не пройдете через массив, поэтому, когда вы выводите эхо из цикла (из slider, вызываемого циклом) вывод выходит первым.

ArtisticPhoenix 11.01.2019 18:13

действительно, в этом больше смысла

quakeglen 11.01.2019 18:16

Один из приемов состоит в том, чтобы использовать ob_start() и ob_get_clean(), тогда вы можете выводить эхо из шорткодов, но по-прежнему захватывать вывод в обратном вызове.

ArtisticPhoenix 11.01.2019 18:16
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
3
105
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

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

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

Небольшое примечание: добавление \n приведет к созданию хорошо отформатированного отрисованного HTML (исходного кода), вместо того, чтобы хранить все это в одной строке; просто говорю.

Funk Forty Niner 11.01.2019 18:14

@FunkFortyNiner, вы правы, просто делаете это в демонстрационных целях

quakeglen 11.01.2019 18:18

Да, я знаю Робби :)

Funk Forty Niner 11.01.2019 18:18

Ты? Ха-ха! :-D

scrowler 11.01.2019 18:21

О, конечно, я делаю ржу не могу Edit: О, я думал, вы изначально разместили этот первый комментарий @RobbieAverill, ха; моя вина.

Funk Forty Niner 11.01.2019 18:26

Я подумал - рассмешил меня, хотя

scrowler 11.01.2019 18:28

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

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

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

Другие вопросы по теме