Использование 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" />
Но вместо этого просто выводится эхо: [кнопка] Привет [кнопка] [вход]holololo[вход]
Что я делаю неправильно?
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">