php runtime and server environment

php.ini

php.ini is PHP's main configuration file. It controls runtime behaviour such as error reporting, memory limits, file upload sizes, timezones, extension loading, OPcache, and session settings.

The most important skill is not memorising every directive. It is knowing which configuration file PHP loaded, whether CLI and web PHP load the same settings, and how to prove a change is active.

Finding Loaded Configuration

From the CLI:

php --ini
php -i | grep "Loaded Configuration File"

On Windows PowerShell:

php --ini
php -i | Select-String "Loaded Configuration File"

Typical output shows:

Loaded Configuration File: /etc/php.ini
Scan for additional .ini files in: /etc/php.d

The scan directory is where extension-specific .ini files often live.

CLI And Web PHP Can Differ

CLI PHP and PHP-FPM may load different configuration files.

Example Linux layout:

/etc/php/8.3/cli/php.ini
/etc/php/8.3/fpm/php.ini
/etc/php/8.3/cli/conf.d
/etc/php/8.3/fpm/conf.d

That means this can happen:

CLI memory_limit: -1
FPM memory_limit: 128M

When a setting works in the terminal but not in the browser, verify the web runtime separately.

Inspecting Settings From PHP

Use ini_get() to inspect runtime values:

PHP example
<?php

declare(strict_types=1);

echo 'memory_limit=' . ini_get('memory_limit') . PHP_EOL;
echo 'upload_max_filesize=' . ini_get('upload_max_filesize') . PHP_EOL;
echo 'post_max_size=' . ini_get('post_max_size') . PHP_EOL;
echo 'date.timezone=' . ini_get('date.timezone') . PHP_EOL;

// Prints:
// memory_limit=128M
// upload_max_filesize=2M
// post_max_size=8M
// date.timezone=UTC

This is useful in a local diagnostic route or CLI script.

Important Directives

Common settings you will meet:

memory_limit = 256M
max_execution_time = 30
date.timezone = UTC
display_errors = Off
log_errors = On
error_log = /var/log/php/error.log
upload_max_filesize = 10M
post_max_size = 12M
max_file_uploads = 20

Important relationships:

  • post_max_size must be larger than upload_max_filesize for file uploads.
  • display_errors should usually be off in production.
  • log_errors should be on in production.
  • memory_limit should be high enough for the app, not unlimited by default.
  • date.timezone should be explicit.

Extension Configuration

Extensions may be enabled in the main php.ini or in scanned .ini files.

Examples:

extension=mbstring
extension=pdo_mysql
zend_extension=opcache

Check loaded extensions:

php -m

Check from PHP:

PHP example
<?php

declare(strict_types=1);

foreach (['mbstring', 'pdo_mysql', 'opcache'] as $extension) {
    echo $extension . ': ';
    echo extension_loaded($extension) ? 'loaded' : 'missing';
    echo PHP_EOL;
}

If an extension is loaded in CLI but missing in the browser, compare the CLI and FPM scan directories.

Changing Settings At Runtime

Some settings can be changed with ini_set() during a request. Others can only be changed in configuration files or server configuration.

PHP example
<?php

declare(strict_types=1);

ini_set('display_errors', '0');

echo 'display_errors=' . ini_get('display_errors') . PHP_EOL;

Do not rely on ini_set() for deployment configuration unless the directive is designed to be changed at runtime and the choice belongs in application code.

Verifying A Change

After editing php.ini:

  1. Confirm you edited the file the runtime actually loads.
  2. Restart or reload the relevant runtime if needed.
  3. Check the value from the same SAPI that uses it.

CLI check:

php -i | grep memory_limit

Web check:

PHP example
<?php

declare(strict_types=1);

header('Content-Type: text/plain');

echo 'SAPI: ' . PHP_SAPI . PHP_EOL;
echo 'Loaded ini: ' . (php_ini_loaded_file() ?: 'none') . PHP_EOL;
echo 'memory_limit: ' . ini_get('memory_limit') . PHP_EOL;

Editing the right file but forgetting to reload PHP-FPM is a common mistake.

Configuration Belongs Outside Application Logic

Use php.ini for runtime-level settings. Use environment variables and application configuration for values that belong to the application, such as database hosts, API keys, feature flags, and queue names.

Do not use php.ini as a project secrets file. Runtime configuration and application configuration have different responsibilities.

What You Should Be Able To Do

After this lesson, you should be able to find loaded php.ini files, inspect important directives, explain why CLI and web settings can differ, recognise extension .ini files, and verify that a configuration change is active.

For junior PHP work, this matters because many bugs are configuration bugs. A developer who can prove the loaded configuration saves time and avoids changing application code for a runtime problem.

Practice

Practice: Verify Active php.ini Settings

Create a small diagnostic for checking PHP configuration.

Task

Build a PHP file that prints:

  • PHP_SAPI
  • loaded php.ini
  • memory_limit
  • upload_max_filesize
  • post_max_size
  • date.timezone
  • whether mbstring, pdo_mysql, and opcache are loaded

Use strict types. Keep example output inside the PHP code block as comments.

Afterward, add a short note explaining how you would verify whether CLI and FPM are using different configuration files.

Show solution

This diagnostic reports the values that often explain runtime differences.

PHP example
<?php

declare(strict_types=1);

if (PHP_SAPI !== 'cli') {
    header('Content-Type: text/plain');
}

echo 'SAPI: ' . PHP_SAPI . PHP_EOL;
echo 'Loaded ini: ' . (php_ini_loaded_file() ?: 'none') . PHP_EOL;
echo 'memory_limit: ' . ini_get('memory_limit') . PHP_EOL;
echo 'upload_max_filesize: ' . ini_get('upload_max_filesize') . PHP_EOL;
echo 'post_max_size: ' . ini_get('post_max_size') . PHP_EOL;
echo 'date.timezone: ' . ini_get('date.timezone') . PHP_EOL;

foreach (['mbstring', 'pdo_mysql', 'opcache'] as $extension) {
    echo $extension . ': ';
    echo extension_loaded($extension) ? 'loaded' : 'missing';
    echo PHP_EOL;
}

// Prints:
// SAPI: cli
// Loaded ini: /etc/php.ini
// memory_limit: 128M
// upload_max_filesize: 2M
// post_max_size: 8M
// date.timezone: UTC
// mbstring: loaded
// pdo_mysql: loaded
// opcache: loaded

To compare CLI and FPM, run php --ini in the terminal, then load this diagnostic through the web server. If the loaded php.ini or extension results differ, the SAPIs are using different configuration.