Home / Blog / PHP version fatals Plugin Check will never catch
Receiving QA · WordPress

PHP version fatals Plugin Check will never catch

Your zip passes Plugin Check on PHP 8.2. A host still runs 8.3 with different deprecations — or 7.4 without the extension you assumed. Lint cannot simulate that matrix.

Published August 23, 2026

Plugin Check and the WordPress.org upload pipeline run against one PHP environment at a time. Your laptop might be 8.2. The directory scanner might be 8.1. Your customer’s managed host might still default to 7.4, or jump to 8.3 on the next panel toggle.

Static checks answer: does this code look acceptable on the runtime we chose today? They do not answer: does this plugin survive activation and the first admin click on every PHP version your readme claims to support? Those diverge constantly — and the failure mode is often a white screen, not a friendly notice.

What “PHP version” failures actually look like

Not every mismatch is “function mysql_connect doesn’t exist.” Common ship killers:

  • Parse errors on older PHP. Typed properties, union types, match, or trailing commas in the wrong place — code that never loads on 7.4.
  • Deprecations that become fatals on the next minor. Passing null to internal parameters, dynamic properties, implicit nullable types — fine on 8.1, noisy on 8.2, broken on 8.3 when error handling is strict.
  • Extensions present on your machine, missing on the host. intl, mbstring, imagick, Redis — your dev box has them; production does not until someone reads the error log.
  • Different memory_limit and max_execution_time. Not a “version” issue on paper, but the same symptom: plugin dies on import on shared hosting.
  • Autoload paths that only work in your build. Composer dev dependencies shipped by mistake, or a path that assumes a local monorepo layout.

Plugin Check might flag some deprecated calls statically. It will not run your activation hook on PHP 7.4 and 8.3 in the same afternoon and compare the results.

Why authors discover this after release

Three habits stack the deck against you:

  • One PHP version in dev. Docker pinned to 8.2 means you never see 8.3 deprecations until a user emails.
  • “Requires PHP: 7.4” in the header without testing 7.4. The header is a promise. WordPress.org and users treat it as support, not marketing.
  • Testing only wp-admin on your version. CLI tools, cron, and REST endpoints often boot different code paths — same PHP mismatch, different entry point.

Support tickets that say “white screen after update” or “works on my server” are often this class of bug. Plugin Check green does not close that ticket.

What Plugin Check still does (and stops)

Keep running it for directory hygiene: headers, escaping smells, discouraged APIs, readme shape. Fix what it finds. Then add a runtime matrix pass Plugin Check cannot substitute:

  1. List the PHP versions you claim in Requires PHP — usually two targets: oldest supported and current stable.
  2. On a clean WordPress install per version: upload zip, activate, open the primary wp-admin screen.
  3. Run one observable mission — save a setting, create the entity your plugin owns, hit the REST route if that is how the product works.
  4. Capture fatals from the log when the screen goes blank — not “I refreshed and it worked.”

That is environment QA, not static QA. Different job, different brief.

How to brief testers for PHP/runtime risk

Do not say “test on all PHP versions.” Name the matrix and the observable failure:

  • Environment: WordPress version + PHP version (sandbox label in the brief).
  • Steps: activate → open screen X → perform action Y.
  • Success: screen loads, no fatal, success state visible.
  • Form: activated / blocked; PHP fatal or white screen? (yes/no); log excerpt or recording at the stall.

Isolated sandboxes per tester matter here: you are not poisoning a shared staging site when 8.3 blows up on activation. Each tester gets a fresh install with the version label in the mission.

When to stop widening the matrix

You do not need twelve PHP builds before every dot release. For most plugin ships:

  • Oldest PHP you still claim in the header
  • One modern PHP (what most new hosts default to)
  • Re-run the same brief after you fix a fatal — do not invent a new study

Pattern on two versions beats theater on six. If both pass the same mission, ship or move to the next risk (conflicts, uninstall, etc.).

On QATested

WordPress plugin testing on QATested provisions an isolated sandbox per tester — upload the zip, each person gets wp-admin on a clean install. Brief for PHP/runtime risk: name the version in the mission, one activation + admin path, recording + form. Setup: WordPress plugin sandboxes.

Related: what Plugin Check can’t see in wp-admin · how to test with real users (no staging) · sandboxes vs handing out your staging login.

Related

WordPress plugin testingWordPress plugin sandboxesWhat Plugin Check can’t seeTest with real users (no staging)Sandboxes vs staging login
QATested

End-user product testing for SaaS and web apps. Catch warts before customers do — or validate the improvement you just shipped.

Products
  • QA Testing
  • Usage Learnings
  • Deploy API
  • Product tour
  • Pricing
  • FAQ
Solutions
  • WordPress plugins
  • Mobile apps & web
  • For teams & agencies
  • UX consulting
Get started
  • Post a test
  • For developers
  • For testers
  • Sign in
Company
  • Blog
  • Roadmap
  • Trust
  • Contact

QATested LLC · Doing business as QATested

192 N Wells St #3151, Chicago, IL 60606, United States

hello@qatested.io

QATested LLC operates QATested (qatested.io), a self-serve marketplace where software developers pay to post structured QA tests and independent testers earn guaranteed pay for approved submissions. Payments are processed through Stripe.

© 2026 QATested LLC. All rights reserved.

Privacy Terms Refunds Cookies Tester agreement