Applying a transformation to every scalar in a nested array — trimming decoded JSON, casting numeric strings — usually produces a small recursive function that gets copied between projects. array_walk_recursive() is that function, already written.
$input = ['name' => ' Ada ', 'address' => ['city' => ' Izmir ']];
array_walk_recursive($input, function (&$value) {
$value = is_string($value) ? trim($value) : $value;
});
The value parameter must be taken by reference or nothing changes, which is the mistake to watch for. It only visits leaves — the callback never sees the arrays themselves — so it cannot rename keys or restructure anything, and reaching for it to do that ends in disappointment. For leaf-level normalisation it is exactly right.