How do I get PHP 5.3.8 to read a .user.ini file?

2019-05-18 06:53发布

问题:

I have a Mac OS X server running Apache 2.2.21 and PHP 5.3.8

I would like to set some php.ini style directives on a per-directory basis. According to the PHP manual page, it has been possible since PHP 5.3.0 to override the directives found in the main php.ini runtime configuration file on a per-directory basis by placing a file called ".users.ini" in the directory containing the scripts you want affected.

To me, this solution is highly preferable to using php_value and php_flag instructions contained within a .htaccess file, however the .user.ini file I have created is being ignored by PHP.

According to phpinfo(), my .user.ini files should be re-cached every 5 minutes, and the filename is correctly set to ".user.ini":

user_ini.cache_ttl   300
user_ini.filename    .user.ini

Apache is set to AllowOverides, and I have already confirmed that setting the PHP directive via .htaccess file correctly overrides the ini settings I want to control. The simplest test file I have tried is a .user.ini file containing only the line:

display_errors = On

This doesn't work and the system-wide directory (=Off) is used. However, the equivalent .htaccess file works as expected, overriding the system-wide directive:

php_flag display_errors on

One clue I can find is the mysterious [PHP] at the beginning of the main php.ini file. I couldn't find any mention of this section marker in the manual, so I thought perhaps it was necessary to start the file with [PHP]. I tried adding this to the start of my .user.ini file, and reloaded my page, waited another five minutes, reloaded again, to make sure I was not loading a cached version, and unfortunately it made no difference.

The other clue I found is the equally mysterious statement in the aforementioned PHP manual page describing how to use a .user.ini file: "These files are processed only by the CGI/FastCGI SAPI." Unfortunately I don't know how to confirm that this condition is satisfied other than the line in my phpinfo() output which says: "GATEWAY_INTERFACE CGI/1.1" as there is virtually no other instance of the string "cgi" in my phpinfo() output. I am left to assume that this mystery statement is of little importance and is merely stating that the CGI/FastCGI SAPI does the processing (whatever that means), as opposed to warning me that I need to turn something on. Correct me if I'm wrong.

There is also a mention in the comments on the same .user.ini manual page that processing of .user.ini files won't work when using php-fpm. As far as I know, I'm not using that but if there is an easy way to check, let me know. This does raise the question of whether there are other configuration options or modules which clash with the feature and disable the loading of .user.ini files. Anyone know the answer to that?

For completeness, I include my configure command, in case someone can see some obvious problem, though I don't think I've changed it from the default:

'/private/var/tmp/apache_mod_php/apache_mod_php-53.8~2/php/configure' '--prefix=/usr' '--mandir=/usr/share/man' '--infodir=/usr/share/info' '--disable-dependency-tracking' '--sysconfdir=/private/etc' '--with-apxs2=/usr/sbin/apxs' '--enable-cli' '--with-config-file-path=/etc' '--with-libxml-dir=/usr' '--with-openssl=/usr' '--with-kerberos=/usr' '--with-zlib=/usr' '--enable-bcmath' '--with-bz2=/usr' '--enable-calendar' '--with-curl=/usr' '--enable-exif' '--enable-ftp' '--with-gd' '--with-jpeg-dir=/BinaryCache/apache_mod_php/apache_mod_php-53.8~2/Root/usr/local' '--with-png-dir=/BinaryCache/apache_mod_php/apache_mod_php-53.8~2/Root/usr/local' '--enable-gd-native-ttf' '--with-ldap=/usr' '--with-ldap-sasl=/usr' '--enable-mbstring' '--enable-mbregex' '--with-mysql=mysqlnd' '--with-mysqli=mysqlnd' '--with-pdo-mysql=mysqlnd' '--with-mysql-sock=/var/mysql/mysql.sock' '--without-pear' '--with-iodbc=/usr' '--enable-shmop' '--with-snmp=/usr' '--enable-soap' '--enable-sockets' '--enable-sysvmsg' '--enable-sysvsem' '--enable-sysvshm' '--enable-wddx' '--with-xmlrpc' '--with-iconv-dir=/usr' '--with-xsl=/usr' '--enable-zend-multibyte' '--enable-zip' '--with-pcre-regex=/usr'

(Since you, dear reader, have read this far, if you do see something weird about the above configuration that's unrelated, feel free to mention it in a comment attached to this original post)

回答1:

Gathering some clues from other members' comments, I've been able to do enough research to answer the question properly for future reference.

As explained in the General Installation Considerations section of the PHP documentation, PHP can run alongside an Apache server in one of two ways:

  1. Directly within Apache as an Apache module (mod_php) also known as SAPI (Server Application Programming Interface), or
  2. As a separate executable communicating with Apache through the CGI (Common Gateway Interface) or FastCGI protocol.

When PHP runs as a module within Apache (the default setup on a Mac OS X Server), PHP doesn't have direct access to the filesystem, and Apache supplies everything PHP needs to do its job. Which means picking up last-minute, per-directory configuration options from the filesystem is not an option. This means Apache needs to be responsible for handing any per-directory settings to the PHP processor and therefore must be set via .htaccess (which Apache processes and passes to PHP)

When PHP runs as it's own process (communicating with Apache via CGI or FastCGI), the PHP processor is able to access the directory structure directly before it starts to process your script and so it is possible to load an additional configuration file on a per-directory basis which would affect things like the displaying of parse errors (impossible to decide at runtime of a script, because if the script doesn't parse, PHP can't follow any instructions therein).

So the short version is, if PHP is running as an Apache module, you need to set per-directory configuration directives though an .htaccess file, or switch to Common Gateway Interface.



回答2:

According to the Manual a little further down:

"If you are using Apache, use .htaccess files for the same effect."

Also, are you running PHP in CGI or FastCGI mode through Apache?