Locating the correct php.ini file — and understanding that the CLI and web server often use two entirely different ones — is the first genuine obstacle to increasing PHP's upload size limit or changing any other configuration value.
Finding the currently loaded php.ini via the CLI
php --ini
php -i | grep "Loaded Configuration File"
The critical gotcha: this shows the CLI's php.ini, not necessarily the web server's
A PHP installation commonly maintains two entirely separate php.ini files — one for the command-line interpreter (used when running php script.php directly) and a different one for the version running under Apache or PHP-FPM — editing the CLI's file has zero effect on a value like the upload limit as experienced through an actual web request.
Finding the web server's php.ini specifically
Creating a temporary file with just phpinfo() and loading it through the actual web server (not the CLI) is the most reliable way to confirm which php.ini file is genuinely being used for real web requests — looking for the "Loaded Configuration File" line in its output, the same way php -i reports it for the CLI.
Typical php.ini locations by setup
/etc/php/8.3/apache2/php.ini # Apache module, Debian/Ubuntu
/etc/php/8.3/fpm/php.ini # PHP-FPM, Debian/Ubuntu
/etc/php/8.3/cli/php.ini # CLI, Debian/Ubuntu
Notice the separate apache2, fpm, and cli subdirectories — this is precisely the structure behind the CLI-vs-web-server confusion above; on a PHP-FPM setup specifically, it's the fpm/php.ini file that needs editing for a change to actually affect real web requests.
Increasing the upload size limit
; In the correct php.ini file (web server's, not CLI's)
upload_max_filesize = 20M
post_max_size = 25M
post_max_size must be set to a value equal to or larger than upload_max_filesize — since a file upload is sent as part of the overall POST request body, a post_max_size smaller than the intended upload limit would silently cap the effective maximum below whatever upload_max_filesize alone specifies.
Restarting the correct service after editing
sudo systemctl restart php8.3-fpm
# or, for the Apache module:
sudo systemctl restart apache2
A php.ini change doesn't take effect until the relevant service is restarted (or reloaded, for PHP-FPM) — this is a common point of confusion when a config edit appears to have "no effect," when in fact the running process simply hasn't picked up the new file yet.
Setting the value at runtime instead, for one specific script
ini_set('upload_max_filesize', '20M'); // has NO effect — this specific directive can't be set at runtime
Crucially, upload_max_filesize is one of a small set of directives that cannot be changed via ini_set() at runtime — it must be set in the actual php.ini file (or a server-level override like an .htaccess directive on Apache), which is a common point of confusion for anyone expecting a quick in-code fix.
An alternative for shared hosting without php.ini access: .htaccess
php_value upload_max_filesize 20M
php_value post_max_size 25M
On Apache with mod_php (not PHP-FPM), these directives can be set per-directory via .htaccess — a useful fallback on shared hosting where direct access to edit the server's actual php.ini file isn't available at all.