Цикл PHP Foreach дважды возвращает результат

Я пытаюсь сгенерировать текст для заполнения с помощью php, где заполняемые части хранятся в моей базе данных SQL с фигурными скобками.

Например:

7 5 10 7 21 17 68 {63} {315}

{63} и {315} следует заменить текстом типа ввода с size = "2" для первого и size = "3" для второго.

Я создал регулярное выражение (спасибо SO), и функция preg_match_all возвращает массив с идентифицированными значениями.

$chapitre_name = "7 5 10 7 21 17 68 {63} {315}";
$regex = '~\{([^}]*)\}~';
preg_match_all($regex, $chapitre_name, $matches);
var_dump($matches[1]);

Возвращает массив:

array (size=2)
  0 => string '63' (length=2)
  1 => string '315' (length=3)

Затем, чтобы заменить эти значения, я создал цикл foreach для вычисления длины и создания ввода для каждого значения.

$input = '';
foreach($matches[1] as $key=>$value_resultat ) {
    $length = strlen($value_resultat);
    $input .= '<input type = "text" name = "'.$chapitre_id.'[]" value = "'.$value_resultat.'" size = "'.$length.'" />';
}
$chapitre_name = preg_replace($regex,$input,$chapitre_name);

(Очевидно, что value = "'.$value_resultat.'" предназначен только для целей отладки.)

Моя проблема в том, что когда я echo '<p>'.$chapitre_name.'</p>';, каждое поле повторяется дважды. Например.

<p>7 5 10 7 21 17 68 <input type = "text" name = "646" value = "63" size = "2"><input type = "text" name = "646" value = "315" size = "3"> <input type = "text" name = "646" value = "63" size = "2"><input type = "text" name = "646" value = "315" size = "3"></p>

В качестве точности заполнение пустого текста может содержать любой тип текста или цифры, любой длины, и может быть столько пустых полей, сколько необходимо для каждого администратора, который создает тест.

🤔 А знаете ли вы, что...
PHP был создан в 1994 году Расмусом Лердорфом и первоначально назывался 'Personal Home Page'.


1
54
1

Ответ:

Решено

Вы можете использовать preg_replace_callback как подход:

$chapitre_name =  preg_replace_callback(
    $regex,
    function($matches) use($chapitre_id) {
        return '<input type = "text" name = "'.$chapitre_id.'" value = "'.$matches[1].'" size = "'.strlen($matches[0]).'" />';
    },
    $chapitre_name
);

echo $chapitre_name;

Тест preg_replace_callback

или используя короткий синтаксис с стрелочная функция и sprintf:

$chapitre_name =  preg_replace_callback(
    $regex,
    fn($matches) => sprintf(
        '<input type = "text" name = "%s" value = "%s" size = "%d" />',
        $chapitre_id,
        $matches[1],
        strlen($matches[0])
    ),
    $chapitre_name
);