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.
I used the PHP 5.3 installer to install on a Vista development machine that already had PHP 5.2 running under IIS7 with FastCGI. Unfortunately, any sites I create to test the 5.3 keep returning a 500 error message. I set up the sites to just use the 5.3 handler however this doesn’t seem to help. Is there some other configuration I need to do to run 5.3 along with 5.2?
Jim,
First of all you will need to update you php.ini file to explicitly set the date.timezone setting. Otherwise PHP will return a warning, which will result 500 error message.
Also, as far as I know the PHP installer does not support side by side installation of PHP. However, IIS and FastCGI fully support side by side installations of PHP, but you will need to setup PHP manually. You can refer to PHP Versioning for more details how to setup several PHP versions on the same server.
Hello,
first, great article !!!
For a hosting enviroment, is excellent that each web site have your own php.ini. Is there any way to define what directives may be defined by user?
Marcelo, the php.ini directives are categorized into several buckets based on their changeability. It is not possible to redefine that. You can find the complete list of php.ini directives and their changeability in the List of php.ini directives.
Hi,
nice article, i ran into this looking for a solution after one of our customers requested some changes to php.ini in a php5 site. Currently we’re using Plesk 8.6 for the site administration. I was wondering do you know of any problems that might occur if we where to implement this or would Plesk be unaffected by this?
Kind regards,
Philipp
Philipp, I do not have any experience with using Plesk, so I do not know if this will affect Plestk anyhow.
.user.ini-files are not of much use when you use virtual directories or IIS applications outside the DOCUMENT_ROOT: in that case the settings are only valid for the directory, where the .user.ini file resides, but not for subdirectories, as PHP checks the path against DOCUMENT_ROOT and fails.
For IIS it would be much better to check against APPL_PHYSICAL_PATH: that would make .user.ini files and PHP applications really portable, regardless whether they reside under DOCUMENT_ROOT or not.
On a side note: why did the PHP team decide not to include subfolders for the [PATH=] directive? Who wants to set settings just for a single folder but not for subdirectories?
cheerio :: Arno
ruslany Hello! I wanted to clarify.
In file .user.ini directive with Changeable is “PHP_INI_SYSTEM” will not work?
I need to change the value for a single site “mbstring.func_overload = 0” and for other “mbstring.func_overload = 2”.
Please tell me how this can be done.