Home / Alt manpages / php8.3(1)

  • php8.3(1)
  • User command
  • linux

Run PHP 8.3 Safely from the Linux Command Line

You will finish with a small PHP script you can lint and run, a tested one-liner, a line-by-line filter, and a local development server that is not accidentally exposed to the network. The examples use PHP 8.3.6 on Ubuntu, supplied by php8.3-cli and php8.3-cgi.

Allow about fifteen minutes. You need a shell and the PHP CLI package. Ordinary commands below do not need sudo. The web server example only serves a temporary directory and changes no system configuration. Do not run it as a public service.

1. Confirm which PHP you are running

Start by checking the binary, version and package records. Use the versioned command when you need to be certain that PHP 8.3, rather than another installed PHP version, is being used:

$ command -v php8.3
/usr/bin/php8.3
$ php8.3 -v
PHP 8.3.6 (cli) (built: Sep  2 2026 12:56:02) (NTS)
$ dpkg-query -W -f='${Package} ${Version}\n' php8.3-cli php8.3-cgi
php8.3-cgi 8.3.6-0ubuntu0.24.04.11
php8.3-cli 8.3.6-0ubuntu0.24.04.11

Your build date and package revision may differ. The useful checks are the cli SAPI label and the major and minor version. php-cgi8.3 is a different SAPI for CGI or FastCGI integration; use php8.3 for shell scripts and command-line tests.

Checkpoint: if command -v php8.3 fails, install the distribution's PHP 8.3 CLI package through your normal package-management process. Do not replace a production PHP installation just to follow this guide.

2. Run a safe one-liner

The -r option runs PHP code without opening and closing PHP tags. Quote the PHP code with single quotes so that the shell does not expand PHP variables:

$ php8.3 -r 'echo "cli-ok\n";'
cli-ok

The command returns status 0 when the code runs successfully. Check it immediately if a script is being used in automation:

$ php8.3 -r 'exit(7);'
$ printf 'exit status: %s\n' "$?"
exit status: 7

A common distraction is adding <?php to a -r snippet. The option already supplies the PHP execution context, so tags are not part of this form. If the code contains a shell variable, either escape the dollar sign or use a carefully quoted argument rather than allowing accidental shell substitution.

3. Lint and run a script

Put a real script in a file when it will be reused. This example writes only to /tmp:

$ cat > /tmp/php83-example.php <<'PHP'
<?php
$name = $argv[1] ?? 'world';
echo "Hello, $name\n";
PHP
$ php8.3 -l /tmp/php83-example.php
No syntax errors detected in /tmp/php83-example.php
$ php8.3 /tmp/php83-example.php operator
Hello, operator

The heredoc is quoted, which keeps the shell from expanding PHP syntax while the file is created. The short -l option checks syntax without executing the script. Supplying the filename without -f is the normal compact form; php8.3 -f /tmp/php83-example.php is equivalent.

Checkpoint: lint before running code received from another person or generated by a build step. Linting catches syntax errors, but it does not make untrusted PHP safe to execute.

4. Process standard input line by line

Use -R when the same short piece of PHP should run for every input line. PHP exposes the current text as $argn and its input counter as $argi:

$ printf '%s\n' alpha beta | php8.3 -R 'echo $argi, ": ", strtoupper(trim($argn)), "\n";'
1: ALPHA
2: BETA

This is useful for small transformations, but remember that PHP reads standard input itself in this mode. Code that also reads from STDIN can consume the next line and change what the filter processes. For a longer filter, put the per-line code in a file and use -F. Add -B for setup before input and -E for final output after input.

Keep shell and PHP quoting separate. Quote the whole PHP expression, and do not paste untrusted text into it as source code. Pass changing data through standard input or script arguments instead.

5. Inspect the active CLI configuration

CLI settings are not necessarily the settings used by Apache, PHP-FPM or CGI. Ask this SAPI which configuration files it loaded:

$ php8.3 --ini
Configuration File (php.ini) Path: /etc/php/8.3/cli
Loaded Configuration File:         /etc/php/8.3/cli/php.ini
Scan for additional .ini files in: /etc/php/8.3/cli/conf.d

The installed system also lists the additional files it parsed. Use php8.3 -i for the full information page or php8.3 -m for compiled-in and loaded modules. Use -d name=value for a setting that applies only to the current invocation:

$ php8.3 -d display_errors=1 -r 'echo ini_get("display_errors"), "\n";'
1

Use -c to select a specific php.ini, or -n to use no php.ini at all. These options can materially change application behaviour. Record them in a wrapper or test command rather than quietly relying on a different interactive shell environment.

6. Test the built-in server locally

The CLI has a development server. It serves the current directory unless -t supplies a document root. Create a disposable document root and bind it to loopback:

$ mkdir -p /tmp/php83-web
$ printf '%s\n' '<?php echo "web-ok\n";' > /tmp/php83-web/index.php
$ php8.3 -S 127.0.0.1:8080 -t /tmp/php83-web
[Sat Sep 26 05:17:18 2026] PHP 8.3.6 Development Server (http://127.0.0.1:8080) started

Leave that terminal running, then verify it from another terminal:

$ curl --fail http://127.0.0.1:8080/
web-ok

Stop the server with Ctrl-C. If you used a temporary directory, remove it afterwards with rm -rf /tmp/php83-web after checking the path carefully. This is the one destructive command in the guide: it permanently removes that disposable directory and its contents.

Do not bind this server to 0.0.0.0 or another externally reachable address for a normal test. The PHP manual describes it as a development server, not a production web server. It is single-threaded by default, has no production hardening, and should not be placed on a public network. A router script can handle each request, but that is still a development workflow, not a deployment boundary.

Done means

  • php8.3 -v identified the expected CLI version and package.
  • A -r one-liner ran without PHP tags and returned the expected status.
  • A reusable script passed -l before it was executed.
  • Line processing used $argn and $argi without accidentally consuming standard input.
  • --ini confirmed which CLI configuration was active.
  • The development server was bound to loopback, tested, and stopped.