codBase`) отдаёт строки из БД в UTF-8 и выводит * страницы в UTF-8 — на этой границе строки перекодируются, как в штатных модулях ядра. * Всё, что уходит в Монету (JSON, XML), — UTF-8. */ final class HostCharset { private function __construct() {} public static function isUtf8Shop(): bool { $base = $GLOBALS['PHPShopBase'] ?? null; return is_object($base) && isset($base->codBase) && ($base->codBase === 'utf-8'); } /** * Строка из БД магазина -> cp1251. */ public static function fromDatabase(string $value): string { if (!self::isUtf8Shop()) { return $value; } $converted = iconv('UTF-8', 'Windows-1251//IGNORE', $value); return ($converted === false) ? '' : $converted; } /** * Строка модуля (cp1251) -> кодировка БД магазина. */ public static function toDatabase(string $value): string { return self::isUtf8Shop() ? self::toUtf8($value) : $value; } /** * HTML модуля (cp1251) -> кодировка страницы магазина. */ public static function toPage(string $html): string { return self::isUtf8Shop() ? self::toUtf8($html) : $html; } /** * cp1251 -> UTF-8 для Монеты. Байт 0x98 в cp1251 не определён — на нём iconv вернул бы false * на всю строку (название позиции в чеке стало бы пустым), поэтому он удаляется заранее. * Не //IGNORE: его поддержка зависит от реализации iconv (glibc — да, musl — нет). */ public static function toUtf8(string $value): string { $converted = iconv('Windows-1251', 'UTF-8', str_replace("\x98", '', $value)); return ($converted === false) ? '' : $converted; } }