Библиотека "phpqrcode" в вашем случае кодирует количество символов вместо количества байтов строки UTF-8. Вот почему строка усекается. Если вы кодируете только текст на английском языке Engli sh, строка не будет усечена. Усечение происходит только с символами кириллицы c, поскольку для кодирования каждого символа кириллицы c в UTF-8 требуется 2 байта, а не один байт для латинского.
Интересно, что в демонстрационном примере библиотека на странице автора правильно кодирует символы кириллицы c.
Усечение происходит в вашем случае, потому что вы используете следующие параметры в файле php .ini:
mbstring.func_overload = 2
mbstring.internal_encoding = "UTF-8"
Если вы удалите mbstring.func_overload
(устарело с PHP 7.2.0) из php.ini
или установить его 0, библиотека "phpqrcode" начнет работать правильно. В противном случае функция strlen()
, используемая библиотекой, будет возвращать количество символов, а не количество байтов в строке октетов с кодировкой UTF8, тогда как str_split()
, другая функция, используемая библиотекой, всегда будет возвращать количество байтов, поскольку на него не влияет mbstring.func_overload
. В результате ваши QR-коды будут содержать усеченные строки.
Поскольку вы используете CMS Bitrix Site Manager, удаление mbstring.func_overload
из php.ini
может быть проблематичным c, пока Битрикс не обновит CMS не полагаться на эту устаревшую функцию. Вы можете найти дополнительную информацию о надежности Битрикс для устаревшей функции по адресу https://idea.1c-bitrix.ru/remove-dependency-on-mbstring-settingsfuncoverload/ или https://idea.1c-bitrix.ru/?tag=4799
Поскольку вы не можете изменить конфигурацию php.ini
во время выполнения. раз вы можете попытаться настроить свой веб-сервер так, чтобы параметры php настраивались на уровне каталога. В противном случае вы можете исправить код библиотеки «phpqrcode», чтобы он работал корректно, хотя бы частично, в вашем случае, чтобы не полагаться на функцию strlen()
. Для этого отредактируйте файл qrencode.php
следующим образом. Сначала замените константу $eightbit
класса QREncode
с false
на true
. Во-вторых, в функции encodeString8bit
замените
$ret = $input->append(QR_MODE_8, strlen($string), str_split($string));
на
$arr = str_split($string);
$len = count($arr);
$ret = $input->append(QR_MODE_8, $len, $arr);
В любом случае, поскольку библиотека "phpqrcode" в настоящее время не поддерживает режим расширенных интерпретаций каналов (ECI), вы не может надежно кодировать символы кириллицы c с библиотекой. Он использует режим 8-bit string
хранения текста в QR-коде, который по умолчанию может содержать только символы ISO-8859-1 (Latin-1), если набор символов по умолчанию не изменен в записи ECI. Но библиотека не может вставить запись ECI в QR-код, чтобы показать, что текст имеет кодировку UTF-8, а не ISO-8859-1. Некоторые приложения декодирования будут автоматически определять неправильную кодировку и правильно отображать строку, в то время как некоторые (совместимые) могут этого не делать.
В заключение, поскольку "phpqrcode" в настоящее время не поддерживает ECI, вы не можете надежно кодировать кириллицу c символов с ним, но вы можете, по крайней мере, заставить его не обрезать строку, как я показал выше.