Search code examples
phpdockeralpine-linuxicuintl

php IntlDateFormatter not working in my docker container


I want to display the date and more precisely the names of the months according to the locale of the country, but for some reason the class IntlDateFormatt for the name of the month returns the record M05, which I understand as the month and its number. And I don't understand why this is happening because I installed the icu-dev library, and as described in the documentation, this locale is not from the user's system, but from the icu library:

The locale that will be used in intl functions when none is specified (either by omitting the corresponding argument or by passing NULL). These are ICU locales, not system locales. The built-in ICU locales and their data can be explored at » http://demo.icu-project.org/icu-bin/locexp.

Dockerfile:

FROM php:7.4-cli-alpine

RUN apk update && apk add icu-dev bash autoconf g++ make zlib-dev libzip-dev libpng-dev libwebp-dev freetype-dev libjpeg-turbo-dev libpng-dev supervisor \
    && docker-php-ext-configure \
        gd --enable-gd --with-freetype --with-jpeg --with-webp \
    && docker-php-ext-install intl pdo_mysql gd zip

RUN mv $PHP_INI_DIR/php.ini-development $PHP_INI_DIR/php.ini

COPY ./common/php/conf.d /usr/local/etc/php/conf.d
COPY ./development/php-cli/conf.d /usr/local/etc/php/conf.d

RUN apk add unzip

# fix work iconv library with alphine
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

COPY ./common/wait-for-it.sh /usr/local/bin/wait-for-it
RUN chmod 555 /usr/local/bin/wait-for-it

RUN addgroup -g 1000 app && adduser -u 1000 -G app -s /bin/sh -D app

ENV COMPOSER_ALLOW_SUPERUSER 1

RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/bin --filename=composer --quiet \
    && rm -rf /root/.composer/cache

WORKDIR /app

CMD ["supervisord", "-c", "/etc/supervisor/conf.d/supervisor.conf"]

USER app

My test script, ua_UK is a correct locale:

$formatter = new \IntlDateFormatter(
    'uk_UA',
    IntlDateFormatter::FULL,
    IntlDateFormatter::FULL
);

$formatter->setPattern('MMMM');

echo $formatter->format(new \DateTime()); //M05

What is the reason for this behavior?


Solution

  • I solved this problem, as I thought it was the work of icu-dev, I found this image in which this problem was solved, but want to warn that the build time with these steps increased by 300 seconds, which is acceptable for me, although I would not say what was good was 70, it became ~400, as you can see, it is not good, if you understand a docker and such little things, then maybe you could optimize these points or explain why there is a problem with the icu-dev library, but for now, I will leave a short code what should be added to the image:

    FROM php:7.4-cli-alpine
    
    ENV ICU_RELEASE=73.1
    
    # Remove icu-dev from dependencies
    RUN apk add --update --no-cache bash autoconf g++ make zlib-dev libzip-dev libpng-dev libwebp-dev freetype-dev libjpeg-turbo-dev \
        && docker-php-ext-configure gd --enable-gd --with-freetype --with-jpeg --with-webp \
        && docker-php-ext-install pdo_mysql gd zip \
        # And we need these three lines to install icu through the official repository, followed by its unpacking and build
        && cd /tmp && curl -Ls https://github.com/unicode-org/icu/releases/download/release-$(echo $ICU_RELEASE | tr '.' '-')/icu4c-$(echo $ICU_RELEASE | tr '.' '_')-src.tgz > icu4c-src.tgz \
        && cd /tmp && tar xzf icu4c-src.tgz && cd /tmp/icu/source && echo "#define FALSE 0" >> config.h && echo "#define TRUE 1" >> config.h && ./runConfigureICU Linux && make && make install && rm -rf /tmp/icu /tmp/icu4c-src.tgz \
        && docker-php-ext-install intl
    
    ...
    
    

    I hope that someone will come across this answer and be able to optimize the build from 300 seconds to some reasonable numbers.