Skip to content

/flags/php/php-d-ini-setting

php -d: override a php.ini setting for one run (memory_limit, display_errors)

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
tool
PHP
command
php
flag
-d foo[=bar]
default
values come from php.ini (and the built-in defaults when no php.ini is loaded)

php -d memory_limit=512M script.php runs the script as if php.ini contained memory_limit = 512M. The option sets any ini directive for that one process, overriding the loaded php.ini, and can be repeated: php -d display_errors=1 -d error_reporting=E_ALL test.php. It is the quickest fix for a CLI job that dies with Allowed memory size exhausted, and for testing a setting before editing php.ini.

Effect of -d

The example uses PHP 8.4 compiled to WebAssembly (php-wasm, from the WordPress Playground project), whose CLI takes the same arguments as php in a terminal:

bash
npm init -y >/dev/null
npm install --silent --no-audit --no-fund @php-wasm/node@3.1.56 @php-wasm/universal@3.1.56 >/dev/null 2>&1
cat > php.mjs <<'JS'
// Minimal "php" command: copies *.php files into the virtual file system and runs the CLI
import fs from "node:fs";
import { PHP } from "@php-wasm/universal";
import { loadNodeRuntime } from "@php-wasm/node";
const php = new PHP(await loadNodeRuntime("8.4", { emscriptenOptions: { processId: 1 } }));
php.mkdir("/app");
for (const f of fs.readdirSync(".").filter((f) => f.endsWith(".php"))) php.writeFile(`/app/${f}`, fs.readFileSync(f));
php.chdir("/app");
const r = await php.cli(["php", ...process.argv.slice(2)]);
process.stdout.write(await r.stdoutText);
process.stdout.write(await r.stderrText);
process.exit(await r.exitCode);
JS
echo "== memory_limit"
node php.mjs -r 'echo ini_get("memory_limit"), PHP_EOL;'
node php.mjs -d memory_limit=512M -r 'echo ini_get("memory_limit"), PHP_EOL;'
node php.mjs -d memory_limit=-1 -r 'echo ini_get("memory_limit"), PHP_EOL;'
echo "== error_reporting without warnings"
node php.mjs -d 'error_reporting=E_ALL & ~E_WARNING' -r 'echo $undefined; echo "no warning shown", PHP_EOL;'
echo "== unknown directive"
node php.mjs -d no_such.setting=1 -r 'var_dump(ini_get("no_such.setting"));'
echo "== invalid value"
node php.mjs -d memory_limit=lots -r 'echo ini_get("memory_limit"), PHP_EOL;' 2>&1 | sed -n '2p'

Output

== memory_limit
256M
512M
-1
== error_reporting without warnings
no warning shown
== unknown directive
bool(false)
== invalid value
Warning: Invalid "memory_limit" setting. Invalid quantity "lots": no valid leading digits, interpreting as "0" for backwards compatibility in Unknown on line 0

The default here (256M) comes from the php-wasm php.ini; a stock PHP build without php.ini uses 128M. -1 removes the limit. Constants such as E_ALL & ~E_WARNING are evaluated as in php.ini, so quote the value for the shell. A directive PHP does not know is ignored (ini_get returns false), and an invalid quantity produces a startup warning such as Invalid "memory_limit" setting.

Common settings for CLI runs

OptionUse
-d memory_limit=-1No memory limit (Composer, imports, PHPStan)
-d memory_limit=1GRaise the limit to a fixed value
-d display_errors=1 -d error_reporting=E_ALLShow every notice and warning while debugging
-d display_errors=stderrPrint errors to standard error instead of standard output
-d max_execution_time=0No time limit (the CLI default is already 0)
-d xdebug.mode=debugEnable an installed extension feature for one run
-d extension=intlLoad a shared extension that php.ini does not load
-d opcache.enable_cli=1Use OPcache in the CLI
-d date.timezone=UTCAvoid timezone warnings in scripts

-d name without =value sets the directive to "1".

Order of precedence

  1. Built-in defaults of the PHP binary.
  2. php.ini and the files in the scan directory (see php --ini).
  3. -d options on the command line.
  4. ini_set() calls in the running script, for directives that may be changed at run time.

So -d beats php.ini, but a script that calls ini_set('memory_limit', '128M') lowers it again. -n skips step 2 entirely and runs with built-in defaults plus your -d values.

Pitfalls

  • -d must come before the script name: in php script.php -d memory_limit=1G the option is passed to the script in $argv.
  • Directives whose changeable mode is INI_SYSTEM or INI_PERDIR (for example short_open_tag) cannot be changed with ini_set(), but -d sets them because it is applied at startup.
  • Settings for the web server (for example upload_max_filesize) are not affected; they live in the FPM or Apache configuration.

FAQ

How do I run Composer with more memory?

php -d memory_limit=-1 composer.phar update, or set COMPOSER_MEMORY_LIMIT=-1 when you run the composer command. Both lift the PHP memory limit for that process only.

Can php -d change settings for my web server?

No. -d applies only to the PHP CLI process you start. PHP-FPM and Apache mod_php read their own php.ini and pool configuration; change those files (or php_admin_value in the FPM pool) and reload the service.

Why does php -d upload_max_filesize=64M not help with uploads?

Uploads are handled by the web server's PHP (FPM or mod_php), not by the CLI. The value set with -d is real but lives only in the command-line process that ran it.

Sources