Почему iconv возвращает пустую строку в php:7.4-fpm-alpine docker

#php #docker #encoding #character-encoding #iconv

#php #докер #кодирование #кодировка символов #iconv #docker

Вопрос:

Учитывая следующий код:

 <?php
$mb_name = "湊崎 紗夏";
$tmp_mb_name = iconv('UTF-8', 'UTF-8//IGNORE', $mb_name);
if($tmp_mb_name != $mb_name) {
    echo "tmp_mb_name: {$tmp_mb_name}n";
    echo "mb_name: {$mb_name}n";
    exit;
} else {
    echo "no problem!n";
}
  

Я тестировал в 3v4l.org и это выводит no problem!

Однако на php:7.4-fpm-alpine docker изображении он выводит следующее:

 tmp_mb_name: 
mb_name: 湊崎 紗夏

  

Согласно php.net:

Если вы добавляете строку //IGNORE , символы, которые не могут быть представлены в целевой кодировке, автоматически отбрасываются.

Почему $mb_name не может быть представлено в UTF-8 в php alpine image?

Комментарии:

1. Вы прошли через php.net/ChangeLog-7.php ?

2. Вы уверены, что это не проблема с конфигурацией вашего компьютера? Также, что этот код предположительно делает ?

3. @Sammitch Он должен выводить no problem!

4. @Sammitch Какую конфигурацию я должен сделать?

5. Добавьте error_reporting(-1); , и вы увидите, Notice: iconv(): Wrong charset, conversion from 'UTF-8' to 'UTF-8//IGNORE' is not allowed in /test.php on line 5 потому что, по-видимому , у alpine images просто постоянно возникают проблемы с iconv .

Ответ №1:

Добавьте error_reporting(-1); , и вы увидите:

Обратите внимание: iconv(): неправильная кодировка, преобразование из ‘UTF-8’ в ‘UTF-8 //IGNORE’ не разрешено в /test.php в строке 5

Потому что, по-видимому, изображения alpine просто не работают должным образом с iconv, и разработчики просто отказались от фактического исправления этого. Я думаю, что здесь важно отметить, что PHP не предоставляет никаких официальных изображений docker, это «Официальные» изображения Docker для PHP, которые поддерживаются сообществом docker.

Если вы не возражаете против несколько больших базовых изображений, просто переключитесь на изображение не alpine.

Редактировать: Да, указанное обходное решение, похоже, работает. Чтобы не оставлять полезную информацию за ссылкой, пример Dockerfile:

 FROM php:7.4-alpine

# fix work iconv library with alpine
RUN apk add --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/community/ --allow-untrusted gnu-libiconv
ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so php
  

пример сборки:

 docker build -t php:7.4-alpine-iconv ./
  

Ответ №2:

У меня была такая же проблема. Чтобы изменить поставщика изображения php-fpm с alpine на php.net сработало для меня.

Пример Dockerfile:

 Original:
FROM php:${VERSION}-fpm-alpine 
Edited:
FROM php:${VERSION}-fpm
  

Ответ №3:

Если вы используете alpine:3.14 базовый образ, вы можете просто установить следующий пакет https://pkgs.alpinelinux.org/packages?name=php7-iconvamp;branch=v3.14

Комментарии:

1. На самом деле пакет, похоже, ничего не делает, что немного сбивает с толку, не уверен, какова тогда его цель.

Ответ №4:

Исправлено путем установки php7-mbstring php7-iconv в таком порядке

 RUN apk --no-cache add php7-mbstring php7-iconv
  

Оригинальное решение здесь:https://github.com/docker-library/php/issues/240#issuecomment-355489551

Ответ №5:

Наконец я решаю это в PHP8

после попробуйте множество разных методов

 docker pull php:8.0.14-cli-alpine3.15

docker run -dit --name myphp php:8.0.14-cli-alpine3.15

docker exec -it --user root myphp ash
  

Теперь мы находимся в контейнере :

 apk add --no-cache --virtual .b $PHPIZE_DEPS curl-dev openssl-dev pcre-dev pcre2-dev zlib-dev wget build-base php8-dev nano

apk add --no-cache --repository https://dl-3.alpinelinux.org/alpine/edge/testing/ gnu-libiconv-dev

mv /usr/bin/gnu-iconv /usr/bin/iconv

mv /usr/include/gnu-libiconv/*.h /usr/include

rm -fr /usr/include/gnu-libiconv

mkdir -p /tmp/q

cd /tmp/q

wget https://secure.php.net/distributions/php-8.0.14.tar.gz

tar xzf php-8.0.14.tar.gz

cd php-8.0.14/ext/iconv

phpize

./configure --with-iconv=/usr
  

ОШИБКА

configure: error: iconv does not support errno

Попробуйте решить это :

 nano configure
  

Теперь удалите блок «else» (который содержит iconv does not support errno сообщение об ошибке)

Продолжить

 ./configure --with-iconv=/usr

make

make install

mkdir -p /etc/php8/conf.d

echo "extension=iconv.so" > /etc/php8/conf.d/iconv.ini

apk del .b

cd

rm -fr /tmp/q
  

Тест

 php -m | grep iconv

php -i | grep iconv

php -r 'echo iconv("UTF-8","UTF-8//IGNORE","Axe9 B"),PHP_EOL;'