Да, эта тема с json_encode в 8.4 реально странная. У меня тоже были случаи, когда при обычных настройках вывод выглядел как-то дергано, хотя вроде всё было в UTF-8. Вижу, ты написал, что header с charset иногда помогает - у меня так же, но далеко не всегда. Бывает, что mbstring вроде настроен нормально, а всё равно где-то накрывается. Похоже, что в этой версии что-то с буферами или внутренними кодировками изменили, и это почему-то ломает всё. Я пока не лез глубоко, просто делаю явную конвертацию, чтобы хотя бы избавиться от ошибок. Но это, конечно, больше костыль, а не нормальное решение.