Можно ли добавить нативную функцию?

Можно ли заменить данную функцию на использование `array_walk_recursive`? Если да, то как будет выглядеть изменённый код? 

Я пробую использовать `array_walk_recursive`, но получаю следующую ошибку: 

```php
$array = [
    'a' => [
        'b' => '<script>alert("XSS")</script>'
    ]
];

array_walk_recursive($array, 'htmlspecialchars'); // htmlspecialchars(): Argument #2 ($flags) must be of type int, string given

var_dump($array);
```

Также у меня есть вопрос: сохранит ли `array_walk_recursive` структуру исходного массива? Поскольку, на мой взгляд, он может преобразовать массив в одномерный, а мне необходимо сохранить исходную структуру. Правильно ли я понимаю?
  • 27 января 2025 г. 9:54
Ответы на вопрос 3
Да, вы можете воспользоваться функцией `array_walk_recursive`, но для этого нужно немного модифицировать вашу реализацию. Ошибка, которую вы видите, связана с тем, что функция `htmlspecialchars` принимает больше аргументов, чем предусмотрено для передачи в `array_walk_recursive`. 

Чтобы исправить это, вам нужно создать обертку для функции `htmlspecialchars`, которая будет корректно работать с `array_walk_recursive`. Пример кода может выглядеть так:

```php
$array = [
    'a' => [
        'b' => '<script>alert("XSS")</script>',
    ]
];

// Обертка для htmlspecialchars, чтобы передать только значение элемента массива
function htmlspecialchars_wrapper(&$value, $key) {
    $value = htmlspecialchars($value);
}

array_walk_recursive($array, 'htmlspecialchars_wrapper');

var_dump($array);
```

Теперь, что касается вашего второго вопроса: `array_walk_recursive` сохраняет исходную структуру массива и не преобразует его в одномерный массив. Вместо этого он обходит массив рекурсивно, сохраняя вложенные структуры. Таким образом, ваш массив останется многомерным и будет иметь ту же структуру, что и исходный массив, только с обработанными значениями.

Поэтому использовать `array_walk_recursive` будет правильным решением для вашей задачи!
<pre><code>array_walk_recursive($array, fn (&amp;$val) =&gt; $val = htmlspecialchars($val));</code></pre> <br/> 1. в callback-функцию передаётся 2 параметра (значение и ключ), но htmlspecialchars вторым параметром принимает флаги, а не ключи массива. Поэтому искусственно передаём только один. <br/> 2. array_walk сам по себе не меняет значения, поэтому передаёт значения по ссылке (&)
Можно, но не нужно. <br/> <br/> Функция, которая пытается проискейпить все данные скопом сама по себе не нужна. Каждое значение надо форматировать отдельно. <br/> И уж тем более функция, которая портит исходные данные. Представим, что одну и ту же информацию мы отправляем по емейлу, и в СМС. Сначала проискейпим HTML для шаблона письма, а потом эти же данные отправим в SMS... И там будут эти <code>&amp;quot;</code> <br/> И уж тем более функция, которой требуется <b>доступ к свойству объекта на запись</b> , который далеко не всегда есть.
Похожие вопросы