Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proper iconv #240

Closed
davidsteinsland opened this issue Jun 7, 2016 · 46 comments
Closed

Proper iconv #240

davidsteinsland opened this issue Jun 7, 2016 · 46 comments

Comments

@davidsteinsland
Copy link

iconv is not working as expected on a vanilla php image. The solution is to install GNUs libiconv:
https://ftp.gnu.org/pub/gnu/libiconv/
... and linking this with php during configure process, or give the GNU library precedence:

ENV LD_PRELOAD /usr/local/lib/preloadable_libiconv.so

In any case, this script should not produce errors (as it does on current php images):

ini_set('display_errors', '1');
error_reporting(-1);

// should NOT produce:
// iconv(): Wrong charset, conversion from `UTF-8' to `ASCII//TRANSLIT' is not allowed in [...]
iconv("UTF-8", "ASCII//TRANSLIT", "foobar");

Current work-around:

RUN rm /usr/bin/iconv \
  && curl -SL http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz | tar -xz -C . \
  && cd libiconv-1.14 \
  && ./configure --prefix=/usr/local \
  && curl -SL https://raw.githubusercontent.com/mxe/mxe/7e231efd245996b886b501dad780761205ecf376/src/libiconv-1-fixes.patch \
  | patch -p1 -u  \
  && make \
  && make install \
  && libtool --finish /usr/local/lib \
  && cd .. \
  && rm -rf libiconv-1.14

ENV LD_PRELOAD /usr/local/lib/preloadable_libiconv.so
@ncopa
Copy link
Contributor

ncopa commented Sep 28, 2016

Technically the musl behavior is correct according POSIX as explained in related issue: akrennmair/newsbeuter#364 (comment)

@Flowman
Copy link

Flowman commented Mar 28, 2017

This workaround works fine in alpine 3.3 but if I try to compile php on 3.5 I get this error. Same docker file but changed the version.

ext/gd/libgd/.libs/gdkanji.o: In function `do_convert':
/tmp/php/ext/gd/libgd/gdkanji.c:349: undefined reference to `libiconv_open'
/tmp/php/ext/gd/libgd/gdkanji.c:364: undefined reference to `libiconv'
/tmp/php/ext/gd/libgd/gdkanji.c:380: undefined reference to `libiconv_close'
ext/iconv/.libs/iconv.o: In function `php_iconv_stream_filter_dtor':
/tmp/php/ext/iconv/iconv.c:2565: undefined reference to `libiconv_close'
ext/iconv/.libs/iconv.o: In function `php_iconv_stream_filter_ctor':
/tmp/php/ext/iconv/iconv.c:2591: undefined reference to `libiconv_open'
ext/iconv/.libs/iconv.o: In function `_php_iconv_strlen':
/tmp/php/ext/iconv/iconv.c:754: undefined reference to `libiconv_open'
/tmp/php/ext/iconv/iconv.c:778: undefined reference to `libiconv'
/tmp/php/ext/iconv/iconv.c:812: undefined reference to `libiconv_close'
ext/iconv/.libs/iconv.o: In function `_php_iconv_appendl':
/tmp/php/ext/iconv/iconv.c:474: undefined reference to `libiconv'
/tmp/php/ext/iconv/iconv.c:508: undefined reference to `libiconv'
ext/iconv/.libs/iconv.o: In function `_php_iconv_mime_decode':
/tmp/php/ext/iconv/iconv.c:1504: undefined reference to `libiconv_open'
/tmp/php/ext/iconv/iconv.c:1997: undefined reference to `libiconv_close'
/tmp/php/ext/iconv/iconv.c:2000: undefined reference to `libiconv_close'
/tmp/php/ext/iconv/iconv.c:1615: undefined reference to `libiconv_close'
/tmp/php/ext/iconv/iconv.c:1618: undefined reference to `libiconv_open'
/tmp/php/ext/iconv/iconv.c:1615: undefined reference to `libiconv_close'
/tmp/php/ext/iconv/iconv.c:1618: undefined reference to `libiconv_open'
/tmp/php/ext/iconv/iconv.c:1618: undefined reference to `libiconv_open'
ext/iconv/.libs/iconv.o: In function `php_iconv_stream_filter_append_bucket':
/tmp/php/ext/iconv/iconv.c:2716: undefined reference to `libiconv'
/tmp/php/ext/iconv/iconv.c:2637: undefined reference to `libiconv'
/tmp/php/ext/iconv/iconv.c:2715: undefined reference to `libiconv'
ext/iconv/.libs/iconv.o: In function `_php_iconv_substr':
/tmp/php/ext/iconv/iconv.c:875: undefined reference to `libiconv_open'
/tmp/php/ext/iconv/iconv.c:899: undefined reference to `libiconv'
/tmp/php/ext/iconv/iconv.c:954: undefined reference to `libiconv_close'
/tmp/php/ext/iconv/iconv.c:958: undefined reference to `libiconv_close'
/tmp/php/ext/iconv/iconv.c:907: undefined reference to `libiconv_open'
ext/iconv/.libs/iconv.o: In function `_php_iconv_mime_encode':
/tmp/php/ext/iconv/iconv.c:1193: undefined reference to `libiconv_open'
/tmp/php/ext/iconv/iconv.c:1207: undefined reference to `libiconv_open'
/tmp/php/ext/iconv/iconv.c:1378: undefined reference to `libiconv'
/tmp/php/ext/iconv/iconv.c:1410: undefined reference to `libiconv'
/tmp/php/ext/iconv/iconv.c:1466: undefined reference to `libiconv_close'
/tmp/php/ext/iconv/iconv.c:1469: undefined reference to `libiconv_close'
/tmp/php/ext/iconv/iconv.c:1453: undefined reference to `libiconv'
/tmp/php/ext/iconv/iconv.c:1325: undefined reference to `libiconv'
/tmp/php/ext/iconv/iconv.c:1277: undefined reference to `libiconv'
/tmp/php/ext/iconv/iconv.c:1309: undefined reference to `libiconv'
ext/iconv/.libs/iconv.o: In function `php_iconv_string':
/tmp/php/ext/iconv/iconv.c:578: undefined reference to `libiconv_open'
/tmp/php/ext/iconv/iconv.c:590: undefined reference to `libiconv'
/tmp/php/ext/iconv/iconv.c:608: undefined reference to `libiconv'
/tmp/php/ext/iconv/iconv.c:618: undefined reference to `libiconv_close'
ext/iconv/.libs/iconv.o: In function `_php_iconv_strpos':
/tmp/php/ext/iconv/iconv.c:1002: undefined reference to `libiconv_open'
/tmp/php/ext/iconv/iconv.c:1030: undefined reference to `libiconv'
/tmp/php/ext/iconv/iconv.c:1144: undefined reference to `libiconv_close'
collect2: error: ld returned 1 exit status
make: *** [Makefile:281: sapi/cli/php] Error 1

Any magic I'm missing?

@kabudu
Copy link

kabudu commented May 26, 2017

I came across this gist which may help! (adjust for your version of PHP)

https://gist.github.com/guillemcanal/be3db96d3caa315b4e2b8259cab7d07e

@alexanderilyin
Copy link

alexanderilyin commented May 30, 2017

A little bit cleaner hack:

RUN apk add --no-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing gnu-libiconv
ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so

Test case:

php -d error_reporting=22527 -d display_errors=1 -r 'var_dump(iconv("UTF-8", "UTF-8//IGNORE", "This is the Euro symbol '\''€'\''."));'
Notice: iconv(): Wrong charset, conversion from `UTF-8' to `UTF-8//IGNORE' is not allowed in Command line code on line 1

If you don't get this notice it means it works as expected.

@delmicio
Copy link

delmicio commented Jun 1, 2017

@alexanderilyin should that code fix this issue? I can't make it work.
image

This is my dockerfile

RUN apk add -U --no-cache \
    autoconf \
    imap-dev \
    libxml2-dev \
    libpng-dev \
    alpine-sdk \
    mariadb-dev \
    zlib-dev \
    libxslt-dev \
    libjpeg-turbo-dev \
    libmcrypt-dev \
    icu-dev \
    gettext-dev \
    && docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr/include \
    && docker-php-ext-configure intl --enable-intl \
    && docker-php-ext-configure imap --with-imap --with-imap-ssl \
    && docker-php-ext-install \
        calendar \
        mysql \
        mysqli \
        bcmath \
        soap \
        xsl \
        gd \
        mbstring \
        pdo \
        pdo_mysql \
        zip \
        exif \
        mcrypt \
        intl \
        gettext \
        imap \
        iconv \
    && pecl install timezonedb \
    && docker-php-ext-enable timezonedb \
    && apk del --purge autoconf alpine-sdk mariadb-dev \
    && apk add -U mariadb-client-libs \
    && cd /usr/local/bin \
    && curl -sS https://getcomposer.org/installer | php \
    && mv composer.phar composer \
    && rm -rf /var/cache/apk/*

RUN apk add --no-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing gnu-libiconv
ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so php

@kabudu
Copy link

kabudu commented Jun 2, 2017

@delmicio iconv works fully (transliteration included) with this hack, even though it registers as "unknown" in the phpinfo() output.

@alexanderilyin
Copy link

@delmicio here is a "test case":

php -d error_reporting=22527 -d display_errors=1 -r 'var_dump(iconv("UTF-8", "UTF-8//IGNORE", "This is the Euro symbol '\''€'\''."));'
Notice: iconv(): Wrong charset, conversion from `UTF-8' to `UTF-8//IGNORE' is not allowed in Command line code on line 1

If you don't get this notice it means it works as expected.

@delmicio
Copy link

delmicio commented Jun 5, 2017

@alexanderilyin yes it's working with your code, although the version keeps unknown. A mystery.

@npulidom
Copy link

@alexanderilyin solution works great. Tested also with repository http://dl-4.alpinelinux.org/alpine/edge/testing

@ababushkin
Copy link

Confirmed that @alexanderilyin solution works. I altered the URL to be based off a CDN link instead:

RUN apk add gnu-libiconv --update-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing/ --allow-untrusted
ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so php

@tianon
Copy link
Member

tianon commented Dec 22, 2017

This appears to be a quirk of PHP when used with musl, and as noted by ncopa above, is POSIX compliant.

Given that and that this thread documents at least one reasonable workaround for folks for whom the default behavior is unacceptable, I'm going to close. Additionally, I imagine using the Debian variants of the image would likely also work. Thanks! ❤️

@vladkras
Copy link

vladkras commented Jan 5, 2018

In my case it was fixed with by installing php7-mbstring first, then php7-iconv.
I'm not sure if my symfony app uses iconv polyfill, but same error was solved

PS
alpine:3.7
php 7.1.12
symfony 4.0

PSS
Exactly same problem and same fix but Laravel and CentOS

@elkbullwinkle
Copy link

Just bumped into this on php7.4-fpm, running apk add --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/community/ --allow-untrusted gnu-libiconv does not create /usr/lib/preloadable_libiconv.so anymore. However if you do pin the library version to 1.15-r3 as described by @joepagan it works. Thanks for the workaround.

@CybotTM
Copy link

CybotTM commented Jul 21, 2021

PHP (8) has to be built with ./configure --with-iconv=/usr/local after GNU Iconv packages have been installed.

@gsusI
Copy link

gsusI commented Sep 11, 2021

In case someone lands here, facing the Wrong charset issue and wants a built-in solution, rather than to compile the modules, you can do this by installing php7-mbstring php7-iconv in that order.

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

Original solution here: #240 (comment)

Edit: @rufinus, I edited my comment, as I believe it will still be helpful for people landing on this thread.

@rufinus
Copy link

rufinus commented Sep 11, 2021

Fixed by installing php7-mbstring php7-iconv in that order

thats no solution - u just use the module from alpine. this thread is about compiling modules and using official php container.

@tianon
Copy link
Member

tianon commented Sep 13, 2021

If you're going to apk add any PHP package, then FROM php isn't right -- you want FROM alpine instead (since apk add php7* will install Alpine's PHP build, and you don't want two different likely-incompatible copies of PHP).

@gitHusband

This comment has been minimized.

@tianon
Copy link
Member

tianon commented Mar 10, 2022

FYI, #1264 implements upstream's recommendation from https://www.php.net/manual/en/intro.iconv.php to use GNU libiconv instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests