About a year ago I wrote an article about how to enable per-site PHP configuration on IIS with FastCGI. The instructions in that article required some non-trivial manipulations of IIS and FastCGI configuration settings. At that time it was one of the primary options for enabling per site php.ini support (other option was to use the htscanner extension for PHP). Now, with PHP 5.3 final release available, it is much simpler to implement the same configuration because PHP 5.3 has built-in support for per-directory INI settings and for user-defined INI files. This post describes how to use these features of PHP 5.3 with IIS to enable per-site and per-directory PHP configuration.
Assume that you have two web sites in IIS – website1.com and website2.com. The root directory for website1.com is at C:\Inetpub\website1.com\ and the root directory for website2.com is C:\Inetpub\website2.com\ . Let’s say that the PHP application at website1.com does some heavy database activity and hence requires longer script execution time, which in PHP is controlled by max_execution_time setting. Also, let’s say that the PHP application at website2.com is a photo album, where visitors may upload very large image files. Because of that it requires bigger maximum allowed file upload size, which is controlled by the php.ini setting upload_max_filesize.
To enable the above described scenario on IIS, first you need to install PHP 5.3 and configure IIS to work with it. The easiest way is to use PHP Installer available at the community PHP site. Make sure to use the installer for VC9 non-thread-safe build of PHP 5.3 and choose the “IIS FastCGI” option during the installation. Alternatively, you can follow the instructions described in Using FastCGI to Host PHP Applications on IIS 7.0 and create the FastCGI handler/script mapping on the server level, so that it applies to all web sites on the server.
Now you have two options:
- Define the per-site PHP settings in the main php.ini file
- Allow web application owners to define those settings in user defined INI files.
For option #1 open the main php.ini file (if you used PHP installer, then this file will most probably be located at C:\Program Files\PHP\ folder. If you installed from a ZIP archive then the file will be at the same directory where php-cgi.exe file is). Add the following at the end of the file:
[PATH=C:/inetpub/website1.com/] max_execution_time = 300 [PATH=C:/inetpub/website2.com/] upload_max_filesize = 12M
Save the php.ini file and then recycle the application pools for these web sites for the php.ini changes to take effect.
After that you can use phpinfo() or ini_get(‘max_execution_time’) to check that these settings overwrite the default ones:
The output shows that the local value of max_execution_time setting (in the second column) is 300, while the master value, or default, is 30.
Alternatively, if you want to allow web application owners to control PHP settings themselves, you can enable user defined PHP configuration. To do that, add the following setting to main php.ini file:
user_ini.filename = .user.ini
This setting specifies the name to be used for user-specific ini files. Setting this to empty value disables the user defined PHP configuration.
After that create a file called .user.ini in C:\inetpub\website1.com\ folder and place and put this line into it:
max_execution_time = 300
Also, put this line into the file .user.ini in C:\inetpub\website2.com\ folder:
upload_max_filesize = 12M
Note that if your main php.ini file has [PATH] sections that point to the root folders of these sites, then you need to remove those sections; otherwise user defined settings will not take effect.
Again, you can use phpinfo() or ini_get() functions to check that the user defined settings overwrite the default ones:
One more thing that you need to be aware of when you enable the user defined ini files is that the settings in those files are cached by PHP engine to avoid re-reading those files for every request. This means that if the user makes a change to .user.ini file then that change may not take effect right away. Instead it may take effect after the cache time-to-live has expired. The cache TTL value is controlled by the php.ini setting user_ini.cache_ttl, which is set to 300 seconds (5 minutes) by default.