php -d: override a php.ini setting for one run (memory_limit, display_errors)
- 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:
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
| Option | Use |
|---|---|
| -d memory_limit=-1 | No memory limit (Composer, imports, PHPStan) |
| -d memory_limit=1G | Raise the limit to a fixed value |
| -d display_errors=1 -d error_reporting=E_ALL | Show every notice and warning while debugging |
| -d display_errors=stderr | Print errors to standard error instead of standard output |
| -d max_execution_time=0 | No time limit (the CLI default is already 0) |
| -d xdebug.mode=debug | Enable an installed extension feature for one run |
| -d extension=intl | Load a shared extension that php.ini does not load |
| -d opcache.enable_cli=1 | Use OPcache in the CLI |
| -d date.timezone=UTC | Avoid timezone warnings in scripts |
-d name without =value sets the directive to "1".
Order of precedence
- Built-in defaults of the PHP binary.
php.iniand the files in the scan directory (see php --ini).-doptions on the command line.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
-dmust come before the script name: inphp script.php -d memory_limit=1Gthe option is passed to the script in$argv.- Directives whose changeable mode is
INI_SYSTEMorINI_PERDIR(for exampleshort_open_tag) cannot be changed withini_set(), but-dsets 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.