Why does iconv returns empty string in php:7.4-fpm-alpine docker

Viewed 3753

Given the following code:

<?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";
}

I tested in 3v4l.org and it outputs no problem!

However, in php:7.4-fpm-alpine docker image, it outputs the following:

tmp_mb_name: 
mb_name: 湊崎 紗夏

According to php.net:

If you append the string //IGNORE, characters that cannot be represented in the target charset are silently discarded.

Why does $mb_name cannot be represented in UTF-8 in php alpine image?

5 Answers

Add error_reporting(-1); and you'll see:

Notice: iconv(): Wrong charset, conversion from 'UTF-8' to 'UTF-8//IGNORE' is not allowed in /test.php on line 5

Because apparently the alpine images just don't work properly with iconv and the maintainers have simply given up on actually fixing it. I think that it is important to note here that PHP does not provide any official docker images, these are "Docker Official" images for PHP that are maintained by the docker community.

If you don't mind somewhat larger base images just switch to a not-alpine image.

Edit: Yes the noted workaround does seem to work. For the sake of not leaving useful information behind a link, example 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

example build:

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

I had the same problem. To change provider of the php-fpm image from alpine to php.net worked for me.

Dockerfile example:

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

Finally i solve it in PHP8

after try a lot of different methods

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

Now we are in the container :

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

ERROR

configure: error: iconv does not support errno

Try solve it :

nano configure

Now remove "else" block (that contains iconv does not support errno error message)

Continue

./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

Test

php -m | grep iconv

php -i | grep iconv

php -r 'echo iconv("UTF-8","UTF-8//IGNORE","A\xe9 B"),PHP_EOL;'
Related