A very strange problem occurred recently on a Debian 10 (Buster, current stable release): PHP translations using gettext did not work. And to our big surprise this wasn't caused by a wrong usage of gettext or wrong translations files (po and mo), but rather by the Apache module mod_perl. But let's get into the details.
Note: This article will not explain how po and mo files work in combination with gettext. For a good introduction visit this tutorial.
The following file translate.php was created with the following content:
$ cat translate.php
<?php
// Set locale
putenv("LC_ALL=de_CH.UTF-8");
setlocale(LC_ALL, 'de_CH.UTF-8');
// Select translation file
bindtextdomain("homepage", "./locale");
textdomain("homepage");
$results = gettext("Dedicated Hosting Description");
if ($results === "Dedicated Hosting Description") {
echo "Original English was returned. Something wrong\n";
} else {
echo $results;
}
?>
A few explanations concerning this code:
But as soon as translate.php was opened in a browser, the text was not translated:
At this point we assumed a problem in the PHP code. Multiple changes to the code were applied, including:
But nothing worked. We already prepared the text to ask a question on Stackoverflow (and be ready to get insulted) when the PHP script was also launched with the PHP command line (CLI).
To our big surprise, the German translation was returned, when the PHP script was called with the php7.3 cli:
$ php7.3 translate.php
Das ist der deutsche Text.
Wow. So the translation actually works; gettext is working just fine! To compare this again with a browser output, curl was used:
$ curl localhost/translate.php
Original English was returned. Something wrong
And again the translation doesn't work.
Fact now: The PHP translation works fine but as soon as the PHP script is opened via Apache (using mod_php), the translations don't work.
On the research why this happens, one hint was found on a question on Stackoverflow: Gettext not working through php-cli, but works in php-apache. The title itself was already intriguing enough although the problem description is the exact opposite of what we were running into.
Although not really relevant to the OP's question, one suggested answer was:
I just found a solution to the opposite problem: Gettext not working through php-apache, but working in php-cli. [...] Strangely, I just disabled the perl module in Apache and the problem disappeared.
Wait. What?! Why would mod_perl be interfering in a PHP code? We indeed had mod_perl enabled on this web server (for one particular Perl based web-application) so we decided to temporarily disable mod_perl - just for the sake of testing all possible workarounds.
# a2dismod perl
# systemctl restart apache2
And then, all of a sudden, the German translation was showing up in the curl response:
$ curl localhost/translate.php
Das ist der deutsche Text.
Is it really mod_perl or did a simple Apache restart fix something? Let's enable mod_perl and test again:
# a2enmod perl
# systemctl restart apache2
$ curl localhost/translate.php
Original English was returned. Something wrong
The problem is indeed caused by mod_perl. Mind. Blown.
Now that we knew that mod_perl is causing this weird problem, there are two possible ways to solve this on this particular Apache web server:
More interestingly (for the geeks like us) is to find more information on this problem. The closest report to this bug can be found in Mageia Linux's Bugzilla: Bug 25411 Installing apache-mod_perl implies that setlocale has no effect in PHP. In fact, this does sound like the exact same behavior/bug. As Mageia is, according to Distrowatch, an independant Linux distribution and therefore not based on Debian, it does indicate that this is an upstream bug of the Apache mod_perl project.
To make sure this is handled in Debian and that Debian maintainers inform upstream, a new Debian bug report was created against the libapache2-mod-perl2 package: Bug #974922 mod_perl interferes with mod_php locales, unable to use gettext translations.
To complete the picture here, this issue happens on these versions and can be reproduced:
$ dpkg -l| egrep "(libapache2-mod-perl|libapache2-mod-php7.3|apache2-bin)" | awk '{print $2" "$3}'
apache2-bin 2.4.38-3+deb10u3
libapache2-mod-perl2 2.0.10-3
libapache2-mod-php7.3 7.3.19-1~deb10u1
ck from Switzerland wrote on Nov 24th, 2020:
Thanks for your comment, Augusto. And thanks for referring back to this article as source of information. I am still curious what the exact bug in mod_perl is. No answer yet from the Debian bug report.
Augusto M Oliveira from MossorĂ³ - RN, Brazil wrote on Nov 24th, 2020:
I had an issue concerning frontend language in Zabbix application and it proved a fine solution. I was still afraid of undesirable implications as Mod_perl seems to have an important role and is praised for a lot of things but, up till now, everything has gone very well. To give you an idea of my struggle, you may view this topic at Zabbix forum https://www.zabbix.com/forum/zabbix-troubleshooting-and-problems/406728-problem-with-changing-the-language-debian . There I related my experience and gave due credit to your help.
AWS Android Ansible Apache Apple Atlassian BSD Backup Bash Bluecoat CMS Chef Cloud Coding Consul Containers CouchDB DB DNS Database Databases Docker ELK Elasticsearch Filebeat FreeBSD Galera Git GlusterFS Grafana Graphics HAProxy HTML Hacks Hardware Icinga Influx Internet Java KVM Kibana Kodi Kubernetes LVM LXC Linux Logstash Mac Macintosh Mail MariaDB Minio MongoDB Monitoring Multimedia MySQL NFS Nagios Network Nginx OSSEC OTRS Office OpenSearch PGSQL PHP Perl Personal PostgreSQL Postgres PowerDNS Proxmox Proxy Python Rancher Rant Redis Roundcube SSL Samba Seafile Security Shell SmartOS Solaris Surveillance Systemd TLS Tomcat Ubuntu Unix VMWare VMware Varnish Virtualization Windows Wireless Wordpress Wyse ZFS Zoneminder