Меняйте ещё, опять говнокод получился. Во-первых, выходной формат не соответствует тому, что, по вашим же словам, вам было нужно. Во-вторых, входной формат не указан, значение не соответствует ни одному из ожидаемых форматов - значит, для парсинга будет применён Date, так что опять работать будет не во всех браузерах.
Враньё, не получилось - применение new Date не позволит получить '31.12.2021' из '12-31-2021'. Кстати, firefox, например, такую строку распарсить не сможет, будет Invalid Date.
Вы спросили, как рекурсивно обойти вложенные объекты/массивы, изменяя значения в объектах, если ключ соответствует заданному условию. Я показал как. Всё. А сейчас вы спрашиваете, как выполнить замену в строке - это не имеет ни малейшего отношения к исходному вопросу.
Александр Токмаков, лучше. Он, как минимум, выполняет замены так, как это задумано. Чтобы выполнял ваш, ключи в $array должны содержать квадратные скобки - иначе они останутся в строке после замен. А зачем ob_start/get_contents/clean я не понял - в strtr вы можете сразу $message передать.
Александр Токмаков, наверное, вы хотели сказать "в ранних". Замените стрелочную функцию обычной, null coalescing поменяйте на isset или array_key_exists:
Вопрос оформлен отвратительно. И разумеется, с нарушением правил (3.1, 3.2, 3.4, 3.8).
Уберите лишние тэги.
Сделайте более осмысленный заголовок, который хоть как-то будет отражать суть ваших затруднений.
Уберите из текста всё, что не несёт информации о вашей проблеме - приветствие, рассказы о том что вам интересно, Будду, и прочий мусор.
Оберните код в тэг code.
Нет, гадать по представленным огрызкам кода какие ещё могут быть косяки - занятие малоперспективное. Воспроизведите свою ситуацию в песочнице, ссылку сюда.
UPD. Хотя нет, догадаться можно - тех огрызков, что вы показали, достаточно. Дополнил ответ.