Why WordPress and CLI show different PHP versions

A PHP change in a hosting panel can repair public WordPress pages, then leave a scheduled backup, import or WP-CLI maintenance task failing. For a business relying on those background jobs, it is a confusing split. The website loads, but the work meant to maintain it has quietly stayed behind.

Abstract web and command-line PHP runtime paths

Start with two empty records, rather than another version toggle.

Website request

  • PHP executable:
  • SAPI:
  • Loaded configuration file:
  • Relevant extensions:

Command-line task

  • PHP executable:
  • SAPI:
  • Loaded configuration file:
  • Relevant extensions:

What must be collected for each? The runtime that actually handled the request, the configuration it loaded and the modules available to it. Until both records are filled in, changing PHP settings again is mostly guesswork with a control panel attached.

The caller matters more than the version label

WordPress and CLI can show different PHP versions because a browser request and a server-side task may call different PHP executables. The web request commonly reaches PHP through PHP-FPM, Apache or CGI. A cron job, deployment command or WP-CLI task can call a PHP binary directly, often under a different user and environment.

PHP documents that configuration discovery can vary by SAPI, permits separate php-SAPI.ini files and allows command-line options to choose a configuration file. The sensible conclusion is simple: inspect the executable and loaded configuration rather than assuming web PHP and CLI PHP are aligned. The detail is covered in the PHP configuration file documentation.

A browser success only proves that the web-facing PHP runtime processed that browser request. It does not prove that a cron job, WP-CLI command or maintenance script uses the same PHP binary, loads the same configuration files or has the same extensions enabled. That distinction explains why public pages can work while background maintenance remains broken.

Identify the command that actually failed

Find the exact command configured in cron, a hosting scheduler or a deployment script. Preserve it with its error output before editing anything. The PHP path at the start of the command is often the first useful clue.

A generic php command is not necessarily generic in practice. Its destination can depend on the scheduler’s PATH, the account user and server configuration. A task that calls an explicit older binary has already told you where to look.

Take an illustrative hosting-panel upgrade. Public WordPress pages move to PHP 8.2 and behave normally. A nightly maintenance command still calls an older server path and runs PHP 7.4. Updating plugins or switching themes would be a poor first reaction. The command’s own runtime needs checking before anything else.

When several WordPress maintenance jobs, scheduled actions or server tasks have been affected, a broader WordPress website repair review can help establish the boundaries of the issue. For one failed task, keep the initial diagnosis narrow.

Put both runtime records side by side

Record Website request Command-line task Why it matters
PHP executable Server-managed web runtime Exact binary called by the task Different binaries can run different PHP versions
SAPI Often FPM, Apache module or CGI CLI Configuration discovery can vary by SAPI
Loaded configuration Web php.ini and scanned files CLI php.ini and scanned files Limits and extension loading can differ
Extensions Modules available to web PHP Modules available to CLI PHP The task may lack a required extension
Task context Web server user and route Cron user, directory and command Paths and permissions can change outside the browser

For the website request, use a controlled diagnostic method in the hosting environment to record the active details. Do not leave a public PHP information page exposed afterwards. It is an unglamorous tidy-up job, but it matters.

For CLI, record the scheduler user and working directory as well as the PHP identity. A command can have the right version and still fail because it starts in the wrong directory or cannot write where it expects. Keep those findings separate from runtime mismatch.

Check the extensions required by the job

Version mismatch gets the attention, but extensions can be the more precise fault. Web PHP may have curl, mbstring, imagick, mysqli or zip available while CLI does not. The reverse can happen too.

Match the check to the task. An API synchronisation may need curl. A media regeneration task may depend on image support. A backup or update process that fails while creating files may instead be dealing with ownership or directory permissions. If the error points to an inability to write folders, use a WordPress directory ownership check rather than trying to solve a filesystem issue with another PHP change.

Apply one correction, then rerun the same job

Once the records show a meaningful difference, make the smallest correction supported by the evidence. That may mean changing the scheduler to call the intended PHP executable explicitly, aligning the CLI configuration, enabling a missing extension for the relevant runtime or replacing an old binary path in a maintenance command.

  1. Keep the original failing command and output.
  2. Record web and CLI runtime identity side by side.
  3. Confirm the executable and configuration used by the scheduled command.
  4. Check the extensions required for that task only.
  5. Apply the scoped correction in the relevant runtime.
  6. Rerun the exact task, then check the related WordPress route.

Do not settle for refreshing the homepage. Run the same command that failed, under the same scheduler or user where possible, and verify its expected output: a completed backup, generated file, finished import or clear success result.

Keep a web-request failure in its own lane

If public WordPress requests begin returning a 500 response after a PHP change, that is a separate diagnostic boundary. The CLI mismatch may be real, but it does not explain every web failure. Start with the server or PHP error associated with the browser request and follow the WordPress 500 error log diagnosis after a PHP update for that route.

Record which runtime did the work before treating a PHP upgrade as complete. It is less dramatic than toggling a version in a panel, but it prevents the visible half of the system being repaired while scheduled maintenance remains broken.

Send the failing task and both runtime records for a scoped repair assessment.