Make changes to PHP ini values without losing them on an update

If you have ever set up a server yourself, you probably realized, that the default values for PHP don’t really work for modern websites. The upload_max_filesize is set to only 2 MB, which means that you cannot upload anything into the media library of WordPress that is larger than 2 MB. This value is usually one you want to change for any site. But how can you change the value and not risking your modifications to be reverted, one you upgrade PHP or your server.

Changing the global PHP ini values

This blog is running on Ubuntu 22.04 with PHP-FPM running alongside the nginx web server. If I want to make changes to any PHP ini variable, I would make those changes to the file /etc/php/8.1/fpm/php.ini on a global level. As you can see in the file path, you would have to make these changes to the php.ini file of each installed PHP version. You would also need to do the change for any “server API”, so if you also use CGI/FastCGI for some site, you have to make the same changes to the file /etc/php/8.1/fpm/php.ini as well.

The advantage of this change is that any website hosted on this server will use these settings, so you can set good defaults for any site. But as you make changes to global configuration files, you will run into issues once you upgrade your server. When the package manager wants to upgrade the configuration file, it detects changes and asks you to either use the new file, use your modified file or to examine the changes and resolve them yourself. Depending on how many changes you have made, this might be difficult to make.

In order to modify PHP ini values globally, I have added a new file called /etc/php/conf.d/90-custom.ini with only the variables I want to change and them symlink them into the different configuration paths:

$ tree /etc/php/   
/etc/php/
|-- 7.3
|   |-- cgi
|   |   |-- conf.d
|   |   |   |-- 10-mysqlnd.ini -> /etc/php/7.3/mods-available/mysqlnd.ini
|   |   |   |-- ...
|   |   |   `-- 90-custom.ini -> /etc/php/conf.d/90-custom.ini
|   |   `-- php.ini
|   |-- cli
|   |   |-- conf.d
|   |   |   |-- 10-mysqlnd.ini -> /etc/php/7.3/mods-available/mysqlnd.ini
|   |   |   |-- ...
|   |   |   `-- 90-custom.ini -> /etc/php/conf.d/90-custom.ini
|   |   `-- php.ini
|   |-- fpm
|   |   |-- conf.d
|   |   |   |-- 10-mysqlnd.ini -> /etc/php/7.3/mods-available/mysqlnd.ini
|   |   |   |-- ...
|   |   |   `-- 90-custom.ini -> /etc/php/conf.d/90-custom.ini
|   |   |-- php-fpm.conf
|   |   |-- php.ini
|   |   `-- ...
|-- ...
|-- 8.1
|   |-- cgi
|   |   |-- conf.d
|   |   |   |-- 10-mysqlnd.ini -> /etc/php/8.1/mods-available/mysqlnd.ini
|   |   |   |-- ...
|   |   |   `-- 90-custom.ini -> /etc/php/conf.d/90-custom.ini
|   |   `-- php.ini
|   |-- cli
|   |   |-- conf.d
|   |   |   |-- 10-mysqlnd.ini -> /etc/php/8.1/mods-available/mysqlnd.ini
|   |   |   |-- ...
|   |   |   `-- 90-custom.ini -> /etc/php/conf.d/90-custom.ini
|   |   `-- php.ini
|   |-- fpm
|   |   |-- conf.d
|   |   |   |-- 10-mysqlnd.ini -> /etc/php/8.1/mods-available/mysqlnd.ini
|   |   |   |-- ...
|   |   |   `-- 90-custom.ini -> /etc/php/conf.d/90-custom.ini
|   |   |-- php-fpm.conf
|   |   |-- php.ini
|   |   `-- ...
|-- ...
|-- conf.d
|   `-- 90-custom.ini

As the new 90-custom.ini is not a file that package manager would add/update, any changes made in this file would be safe from upgrades.

Changing PHP ini values per site

Sometimes you want or need to change values for a specific site. Then using the global file would not work. If you are using the Apache web server, you might be able to change values using the Apache configuration files or even using the .htaccess file. In this file, you would use something like php_value upload_max_filesize 64M to increase the upload limit. This, although, will only work if you use PHP as an Apache module.

If you use Apache with PHP-FPM or different web server – like I am using nginx – you cannot use the .htaccess file to make any changes to the PHP ini values.

Using the “user_ini” file for per site changes

Fortunately, you have another way to change PHP ini values. This can be done with a “user_ini” file, you usually store in the document root of the site. First, you have to find out what the filename for this file should be. You can find out with the phpinfo() function or by running php -i and searching for the user_ini.filename value. You then create this file and add any changes writing it in the same way as in the php.ini files, so like upload_max_filesize = 64M to change the upload limit.

When you make changes to this file and check if they work, they probably don’t! This does not mean that, that you’ve made a mistake. It probably means that the file was not read by the PHP process. This is because the file is cached. You can find out for how long by looking at the user_ini.cache_ttl value. This is the time, in seconds, the file is cached. If the value is 300, you have to wait up to 5 minutes for changes to be used for the site. If you need the changes to be used immediately, you have to restart the PHP process (like PHP-FPM) or the web server (when you use Apache mit mod_php).

Conclusion

There are multiple ways to make changes to PHP ini variables. When you have to make changes, always make sure to use a method that would not break upgrades (or the changes getting lost with the upgrade). For my own server, I prefer to use the first approach with a global custom ini file. The user_ini file has the advantage that these value could easily be transferred to a new server when migrating a site, so they might be better for PHP systems that need specific values.

Posted by

Bernhard is a full time web developer who likes to write WordPress plugins in his free time and is an active member of the WP Meetups in Berlin and Potsdam.

2 comments » Write a comment

  1. Been looking at many pages for a concise treatment of this issue, with NGINX… Pretty much coming round to these methods anyway.. but your article did confirm the available options. And, was trying to find the global method — wasn’t obvious since not using Apache and custom conf files for each site.

    But, one question I had was.. is there a way to specify either the php development or production .ini file to be used when upgrading server? Seems to always default to production.

    • Unfortunately, I don’t know how ini files are handled by the different operating systems when they get updated. That’s why I’m using this approach now.

Leave a Reply

Your email address will not be published. Required fields are marked *