When PHP won't find existing source files

Submitted by Frederic Marand on

The mystery

There are a number of issues on StackOverflow and elsewhere about the problems met when upgrading to PHP 7, so when I upgraded a Debian Wheezy server this week, I only upgraded to Jessie with its standard 5.6 version, not expecting problems. But of course, there had to be this mystifying error which seems to be most often associated with PHP 7.0 : like Debian bug 709302:

[Wed May 22 14:20:26 2013] [error] [client 127.0.0.1] PHP Fatal error: require_once(): Failed opening required './libraries/php-gettext/gettext.inc' (include_path='.') in /usr/share/phpmyadmin/libraries/select_lang.lib.php on line 389
[Wed May 22 14:20:26 2013] [error] [client 127.0.0.1] PHP Fatal error: /require_once(): Failed opening required /'./libraries/php-gettext/gettext.inc' (include_path='.') in //usr/share/phpmyadmin/libraries/select_lang.lib.php on line 389
[Wed May 22 14:20:26 2013] [error] [client 127.0.0.1] PHP Fatal error: require_once(): Failed opening required './libraries/php-gettext/gettext.inc' (include_path='.') in /usr/share/phpmyadmin/libraries/select_lang.lib.php on line 389

So how do we fix this for 5.6 ?

Diagnosing

On the current Jessie build, this happens in line 436 of select_lang.lib.php, which just does require_once GETTEXT_INC. It didn't seem much, so I looked it at it: a simple echo GETTEXT_INC showed that the file wass expected to be found in the same /usr/share/phpmyadmin/libraries/select_lang.lib.php path.

  • Check disk: file is there. Hmm...
  • check if it can be found in PHP using the basic php -a REPL:
    • realpath()returns the absolute path normally. is_file() and is_readable both return true.
    • Use the same realpath(), is_file() and is_readable() in the PhpMyAdmin code : realpath() return empty, and the two checks return false. WTF ?

So, the file is there, PHP CLI can read it, but PHP mod_apache can't. Looks like a php.ini difference, maybe open_basedir ? Nope, it's empty in both. What can it be ?

The fix

Actually, it turns out open_basedir is indeed set (and problematic) within the PhpMyAdmin configuration, although the php.ini configurations are the same. It is set within the Apache / PhpMyAdmin integration in /etc/phpmyadmin/apache2.conf::

php_admin_value open_basedir /usr/share/phpmyadmin/:/etc/phpmyadmin/:/var/lib/phpmyadmin/

We have a culprit ! The restricted basedir prevents PhpMyAdmin from loading the required file. Let's add the reference PHP directory to that list

php_admin_value open_basedir /usr/share/php/:/usr/share/phpmyadmin/:/etc/phpmyadmin/:/var/lib/phpmyadmin/

Issue fixed !