wimg/php-compatibility
PHP_CodeSniffer ruleset that checks your code for compatibility with different PHP versions, helping you spot syntax and features that would break when upgrading or downgrading PHP.
The Composer package to use today is phpcompatibility/php-compatibility; wimg/php-compatibility is the legacy name. Install it as a dev dependency and let the PHP_CodeSniffer installer register the standard:
composer require --dev phpcompatibility/php-compatibility
composer require --dev dealerdirect/phpcodesniffer-composer-installer
If Composer blocks the installer plugin, allow it in composer.json:
{
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
}
}
Verify PHPCS can see the standard:
vendor/bin/phpcs -i
# should include: PHPCompatibility
If it is not listed, register it manually:
vendor/bin/phpcs --config-set installed_paths vendor/phpcompatibility/php-compatibility
Create a project-level phpcs.xml.dist so the whole team and CI use the same target range:
<?xml version="1.0"?>
<ruleset name="Laravel PHP compatibility">
<description>Check application code against the supported PHP version range.</description>
<file>app</file>
<file>config</file>
<file>database</file>
<file>routes</file>
<file>tests</file>
<exclude-pattern>*/vendor/*</exclude-pattern>
<exclude-pattern>*/storage/*</exclude-pattern>
<exclude-pattern>*/bootstrap/cache/*</exclude-pattern>
<exclude-pattern>*/public/build/*</exclude-pattern>
<arg name="extensions" value="php"/>
<arg name="colors"/>
<arg value="sp"/>
<!-- Match composer.json "require.php" and your CI/deployment PHP versions. -->
<config name="testVersion" value="8.2-8.4"/>
<rule ref="PHPCompatibility"/>
</ruleset>
Run it:
vendor/bin/phpcs
# or explicitly
vendor/bin/phpcs --standard=phpcs.xml.dist
The first high-value use case is checking whether a Laravel app can safely run on your minimum supported PHP version, or whether an upgrade to a newer PHP version will hit removed functions, removed constants, changed signatures, or unsupported syntax. Start with the app/, routes/, config/, database/, and tests/ directories; do not start by scanning vendor/ or generated files.
Where to look first:
vendor/bin/phpcs -i to confirm the standard is installed.vendor/bin/phpcs -e --standard=PHPCompatibility to list the available sniffs.vendor/phpcompatibility/php-compatibility/PHPCompatibility/ruleset.xml to see the standard composition.vendor/phpcompatibility/php-compatibility/PHPCompatibility/ when a result needs explanation.Use testVersion as the contract. Set it to the exact PHP range the app supports. For a Laravel app with "php": "^8.2" and CI on 8.2 through 8.4, use:
<config name="testVersion" value="8.2-8.4"/>
You can override it per run without editing the ruleset:
vendor/bin/phpcs --standard=phpcs.xml.dist --runtime-set testVersion 8.2-8.4
Use 8.2- to mean “8.2 and newer” and -8.4 to mean “up to 8.4.” Avoid guessing: align this with composer.json, Docker images, CI matrix, and production.
Keep compatibility checks separate from formatting. Laravel Pint handles style; PHPCompatibility handles cross-version risk. Add a Composer script so developers run both independently:
{
"scripts": {
"compat": "phpcs --standard=phpcs.xml.dist",
"compat:summary": "phpcs --standard=phpcs.xml.dist --report=summary",
"compat:source": "phpcs --standard=phpcs.xml.dist --report=source"
}
}
Use --report=summary for a fast local overview and --report=source when you want to see which sniff categories are producing findings.
Run focused checks during active development. Full-repo scans are useful in CI; changed-file scans are better locally:
git diff --name-only --diff-filter=ACMRTUXB origin/main...HEAD -- '*.php' \
| xargs -r vendor/bin/phpcs --standard=phpcs.xml.dist
For a specific directory or file:
vendor/bin/phpcs --standard=PHPCompatibility \
--runtime-set testVersion 8.2-8.4 \
app/Http app/Models
Use sniff-level targeting for legacy codebases. If the full standard produces too much noise, run only the categories relevant to the upgrade:
vendor/bin/phpcs --standard=PHPCompatibility \
--runtime-set testVersion 8.2-8.4 \
--sniffs=PHPCompatibility.FunctionUse, \
--sniffs=PHPCompatibility.Classes, \
--sniffs=PHPCompatibility.Constants, \
--sniffs=PHPCompatibility.Syntax \
app
Or exclude a category in the ruleset while you work through it:
<rule ref="PHPCompatibility">
<exclude name="PHPCompatibility.FunctionUse"/>
</rule>
Then reintroduce categories as the codebase gets cleaner.
Wire it into CI at the minimum supported PHP version. PHPCompatibility is static analysis, so it does not need every PHP runtime, but the target range does need to match deployment. A typical GitHub Actions step:
- name: Install dependencies
run: composer install --no-interaction --prefer-dist
- name: Check PHP compatibility
run: vendor/bin/phpcs --standard=phpcs.xml.dist --report=full
If you run a PHP matrix, run the compatibility check once against the minimum deployed PHP version and once against the maximum, or simply use one job with an explicit testVersion range that reflects all deployed versions.
Use targeted inline suppressions for real false positives. Suppress the specific sniff, not the whole line or file:
// phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions -- polyfilled by symfony/polyfill-php80
Prefer phpcs:ignore over phpcs:disable so other compatibility problems in the same file are still reported.
Treat results as review prompts, not automatic fixes. A removed function finding may be solved by a polyfill, a Laravel helper, a conditional function_exists() branch, or replacing the call entirely. On Laravel projects, dynamic calls through the service container, facades, aliases, and variable functions are especially likely to require manual review.
wimg/php-compatibility is legacy. Use phpcompatibility/php-compatibility unless you are deliberately maintaining an old lockfile. Keep PHPCS and PHPCompatibility current enough for the PHP versions you target.phpcs binary. Use vendor/bin/phpcs so the project uses the locked PHPCS and standards.testVersion is the most common misconfiguration. If it is missing or wrong, findings will not match your deployment. Set it explicitly in phpcs.xml.dist and override only for intentional scenarios.8.2-8.4, not 8.2,8.3,8.4. Use 8.2- for “8.2 and above.”phpcs -i does not show PHPCompatibility, check allow-plugins, rerun composer install, or set installed_paths manually.vendor/, storage/, bootstrap/cache/, compiled views, or frontend build output creates noise and slows CI.testVersion or exclusions, rerun with --no-cache or clear the cache file configured for PHPCS.phpcs -s or --report=source. Broad suppressions hide future regressions.config.platform.php says one version and testVersion says another, developers get contradictory signals.vendor/bin/phpcs -s to include source codes in output, then use those codes for targeted ignores, exclusions, or focused CI reports.How can I help you explore Laravel packages today?