Использование preg_replace_callback с шорткодами

Я пытаюсь внедрить короткие коды на своем веб-сайте, чтобы упростить публикацию. То, что я получил до сих пор, выглядит так:

$text = "[button]Hello[button] [input]holololo[input]";
$shortcodes = Array( 'button' => '<button>{content}</button>', 'input' => '<input type="text" value="{content}" />' );
$text = preg_replace_callback('(\[([a-z]+?)\](.+?)\[\\\1\])', function ($matches){ 
   if ($shortcodes[$matches[1]]){ 
            return str_replace('{content}', $matches[2], $shortcodes[$matches[1]]); 
   }else{
     return $matches[0]; 
   } 
}, $text);
echo $text;

Я хочу, чтобы это повторялось: <button>Hello</button> <input type="text" value="holololo" />

Но вместо этого просто эхо: [кнопка]Привет[кнопка] [ввод]голололо[ввод]

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


person Murillio4    schedule 20.02.2014    source источник


Ответы (1)


Две вещи. Во-первых, ваше регулярное выражение выглядит так:

'(\[([a-z]+?)\](.+?)\[\\\1\])'

Вы не хотите экранировать косую черту перед 1, иначе вы буквально ищете «\ 1», а не обратную ссылку. Так что должно быть:

'(\[([a-z]+?)\](.+?)\[\1\])'

Также:

function ($matches) { 

Вы пытаетесь сослаться на $shortcodes в своей функции. Однако это определено вне функции, поэтому у нее нет к ней доступа. Вы должны явно передавать любые неглобальные переменные в функцию. При работе с такой анонимной функцией используйте инструкцию use, поэтому определение вашей функции должно выглядеть так:

function ($matches) use ($shortcodes) {

Внесение этих двух простых изменений дало мне следующий результат:

<button>Hello</button>
<input type="text" value="holololo">
person ChicagoRedSox    schedule 20.02.2014
comment
Он не будет показывать только кнопку, если у меня есть только такие теги: [кнопка][кнопка], и я не так хорош в php, не могли бы вы мне помочь? - person Murillio4; 21.02.2014
comment
@Murillio4 Murillio4 На самом деле это не проблема PHP, просто небольшое изменение в вашем регулярном выражении: (.+?) означает один или несколько любых символов. Если вы измените его на (.*?), это означает ноль или более любого символа. Другими словами, это позволяет ему вообще ни с чем не совпадать. Однако обратите внимание, что это даст вам кнопку без текста. - person ChicagoRedSox; 21.02.2014