I have multiple sites running on Apache2 and PHP on Ubuntu Server. I know PHP has a php.ini file that lets you set values for upload_max_filesize
, max_file_uploads
, upload_tmp_dir
etc. But that applies one value to all sites.
How can set directives for each site? For Eg: I’d like to set upload_max_filesize
to 50M for sitea.com
and upload_max_filesize
to 5M for siteb.com
.
Similarly, I’d like to set unique a session.name
for each sites. How can this be done? I read there’s something called PHP_INI_USER
, PHP_INI_PERDIR
, PHP_INI_SYSTEM
, PHP_INI_ALL
, so how can I do this?
3
Answers
You can use
.htaccess
files per site (or even per-folder) to set PHP configuration values – at least for most settings: if you look in the configuration directives documentation, for every setting that is marked as eitherPHP_INI_PERDIR
orPHP_INI_ALL
you can set these in a.htaccess
file using thephp_value
orphp_flag
commands as documented in PHP’s "How to change configuration settings" document.For example to set
upload_max_filesize
in a website, create a.htaccess
file at the document root of that website and put in it the text:Unfortunately,
max_file_uploads
andupload_tmp_dir
are settings marked asPHP_INI_SYSTEM
and you cannot change them in a.htaccess
file…Your settings are in php.ini indeed. Yet, if you have multiple sites to set, then you can set values inside the
.htaccess
file in the root of the site folder.However, you can create a json file somewhere on your server, let’s assume it’s at /path/settings.json of the format of:
Now, you can create a deploy.php file at all your sites that will run
cat /path/settings.json
via exec, likeYou will then have an array of key-value pairs that can be looped and the setting will be known, like:
and then save
$script
into a file, let’s call it init.php for now. Yourequire_once
this file and then you can maintain a single json file and deploy it per site by running a single cli command. You can even create an sh file that runs all deployment commands so you will be able to deploy everything via a one-liner.The comment by Mike ‘Pomax’ Kamermans explicitly states how this should be done. However PHP manual documentation can be a little off-putting.
Also some clarifiers re the other answers here:
Using a PHP parser file (as described by Lajos Arpad) adds some security risks and a pile of coding, syntax and some processing overhead that really isn’t needed.
.htaccess
does work for setting custom ini directives for some PHP installations but if you’re using "FastCGI" or "CGI" (and possibly suPHP) PHP installations then this will infact crash your website with a 500 error, so instead use a local.user.ini
file as described here. How do I find out my SAPI?ONLY if you are running PHP as an Apache module (eg mod_php), use
.htaccess
. How do I find out my SAPI?PHP suPHP/FastCGI/CGI SAPI
So, how should your aspiration be completed?
1) Look up the Core PHP.ini details.
Read your PHP.ini file for your current version of PHP.
Around line 180 (for PHP 8.1) it should say something like this:
Make a note of this value and I would suggest customising this value (as shown in this example). This value is the file name of the file which will sit in each unique account on the server, holding the account specific "local" settings for the global PHP.ini file.
The file typically sits in the
public_html
folder so should begin with a.
so as to set as hidden by default (see more about this later on). If the file doesn’t exist an an account no core PHP settings are changed.2) Remember/Set the Filename and Create the New Rules
So you now know/ have set the name for your custom PHP file; now generate the file in your account and you can then set the PHP.ini settings you want to customise for this account alone.
For example;
Would contain the following example information:
This information is parsed by PHP and overwrites any corresponding values in the core PHP.ini but only for this account.
3) Customise for Each Account as Needed
For example, for your siteb.com php user ini file it would look more like this:
Would contain the following example information:
You can then check that these account settings are set correctly by exploring
phpinfo()
on each account and noting the local and core differences as displayed.4) Test And Confirm
The core user.ini file in the
/public_html/
path should be all you need for every child file/folder on that account to process (This can sometimes depend on your exact LAMP server setup and your PHP handler).As I say, once you’ve set a test ini file you should run
phpinfo()
to check its values are implemented.If you don’t want to use
phpinfo()
then you can just as easily use[ini_get](https://www.php.net/manual/en/function.ini-get)
to dump sensitive data out to the error log rather than to the browser.5) Security
The user.ini file is typically started with a
.
character to hide it in the directory, but that doesn’t make it untouchable by browser agents, therefore it’s best practise to add a few lines to your.htaccess
to deny access to this file.Some Final Thoughts:
Core PHP.ini values do change in new versions of PHP and so this is why it’s best practise to have different local .ini files for different PHP versions (
.account-php80.ini
,.account-php81.ini
, etc.). Note that eachphp.ini
core will need to explicitly call their respective local user.ini file, as referenced in step 1 above.The principles of the above are outlined in the PHP Manual and it must be noted: