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