Detect the minimum PHP version a piece of code needs to run. It walks the code's AST and flags the language features, functions, classes and constants that were introduced in a given version (5.3 → 8.4).
- PHP 7.4+ (tested on 8.1 – 8.4)
- One AST backend:
- preferred: the native
astextension (fast), or - fallback:
nikic/php-parser— pure PHP, installed via Composer.
- preferred: the native
The ast extension is optional. When it is not loaded the tool automatically
falls back to nikic/php-parser, so composer install alone is enough to run it.
composer install# a single file
./php-version-detector path/to/file.php
# or a whole directory (recursively scans *.php)
./php-version-detector path/to/project/Example output:
----------------------------------------------------------------------------------------------------
v | type | confirmed | evidence | file | line
----------------------------------------------------------------------------------------------------
81 | Feature | Confident | Enums | app/Suit.php | 3
----------------------------------------------------------------------------------------------------
80 | Function | Confident | str_contains | app/Str.php | 12
----------------------------------------------------------------------------------------------------
The image bundles the fast ast extension and the Composer dependencies:
docker build -t php-version-detector .
docker run -t --rm -v $(pwd):/app php-version-detector /app/tests/ast-feed.phpcomposer testCI runs the suite on PHP 8.1 – 8.4 against both the ast extension and the
pure-PHP nikic/php-parser fallback (see .github/workflows/ci.yml).
ast\parse_code() (or the php-parser adapter) produces an AST; a set of
per-version detectors (detect/php*.php) walk every node looking for:
- Features — language constructs (
match, enums, arrow functions, …) - Functions — calls to functions added in a version
- Classes —
new/extendsof classes added in a version - Constants — references to constants added in a version
Findings are Confident unless guarded by a function_exists() / class_exists()
check, in which case they are downgraded to Possible.