为什么 iconv returns 在 php:7.4-fpm-alpine docker 中为空字符串

Why does iconv returns empty string in php:7.4-fpm-alpine 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

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

为什么$mb_name不能在php alpine image中的UTF-8中表示?

加上 error_reporting(-1); 你会看到:

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

因为显然 the alpine images just don't work properly with iconv and the maintainers have simply given up on actually fixing it。我认为这里需要注意 PHP 不提供 任何 官方 docker 图片,这些是 Docker 官方图片 PHP 由 docker 社区维护。

如果您不介意稍大一些的基本图像,只需切换到 not-alpine 图像即可。

编辑: 是的,noted workaround 似乎有效。为了不在 link 后面留下有用的信息,例如 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 ./

我遇到了同样的问题。将 php-fpm 图像的提供者从 alpine 更改为 php.net 对我有用。

Dockerfile 示例:

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

如果您使用的是 alpine:3.14 基本映像,则只需安装以下软件包 https://pkgs.alpinelinux.org/packages?name=php7-iconv&branch=v3.14

已通过按顺序安装 php7-mbstring php7-iconv 修复

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

原解在这里:https://github.com/docker-library/php/issues/240#issuecomment-355489551

最后我在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","A\xe9 B"),PHP_EOL;'