phpdockerencodingcharacter-encodingiconv

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


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?


Solution

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