为什么 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;'
给定以下代码:
<?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;'