Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/binaries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
ref: ${{ inputs.ref }}
- uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
php-version: '8.5'
ini-values: phar.readonly=0
coverage: none
- run: composer install --no-interaction --no-progress
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
php: ['8.2', '8.3', '8.4', '8.5']
php: ['8.5']
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
Expand Down
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,20 @@
phpgraph follows [semantic versioning](https://semver.org) from 1.0.0; what stays stable is listed in
[docs/STABILITY.md](docs/STABILITY.md), and changes only in a major version (2.0.0), announced here.

## 2.0.0 (2026-10-31)

### Changed
- **PHP 8.5 or newer** is needed to run phpgraph from Composer or its PHAR (8.2 before): `composer require` no longer
installs it on PHP 8.2 to 8.4. The binaries and the Docker image bring their own PHP and change nothing for their
users; a project on an older PHP keeps being analysed, whatever PHP it is written for. Nothing else changes: the
commands, the MCP tools and `graph.json` are those of 1.6.0, and every graph of the corpus is identical.
- Builds are faster. The files are parsed by one worker process per processor, with PHP's `pcntl` extension (in the
binaries and the Docker image; not on Windows, where they are parsed one after the other); `PHPGRAPH_WORKERS` sets
the number of workers, `1` parses in one process. The dependencies' signatures are read without the bodies of their
methods, a chain of calls is typed once instead of once per call in it, and the extraction cache reads back only
the files a build reuses. Docker image, 12-thread laptop: Sylius 28 → 10 s, Akeneo 26 → 17 s; with the cache of
the previous build, Sylius 14 → 8 s. Peak memory +12 to +20 % with workers, −4 to −28 % without.

## 1.6.0 (2026-10-30)

### Added
Expand Down
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ ARG PHPGRAPH_VERSION=dev
# image has it. 8.5.12: CVE-2026-109618, remote code execution after an out-of-memory error (GHSA-w8hw-w9fx-j79w).
ARG PHP_MINIMUM=8.5.12
RUN php -r 'if (version_compare(PHP_VERSION, getenv("PHP_MINIMUM"), "<")) { fwrite(STDERR, "PHP " . PHP_VERSION . " is older than " . getenv("PHP_MINIMUM") . "\n"); exit(1); }'
# pcntl: the files are parsed by one worker process per processor (ParallelExtraction).
RUN apk add --no-cache --virtual .build-deps $PHPIZE_DEPS && docker-php-ext-install pcntl && apk del .build-deps
# Opcache with its JIT: builds about 20% faster, the same graph (measured on Sylius and Akeneo).
RUN printf 'opcache.enable_cli=1\nopcache.jit=tracing\nopcache.jit_buffer_size=128M\n' > /usr/local/etc/php/conf.d/phpgraph-opcache.ini
LABEL org.opencontainers.image.title="phpgraph" \
Expand Down
8 changes: 4 additions & 4 deletions README.fr.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<a href="https://github.com/hbenabdallah/phpgraph/actions/workflows/ci.yml"><img src="https://github.com/hbenabdallah/phpgraph/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
<a href="https://packagist.org/packages/hbenabdallah/phpgraph"><img src="https://img.shields.io/packagist/v/hbenabdallah/phpgraph" alt="Version Packagist"></a>
<a href="https://packagist.org/packages/hbenabdallah/phpgraph"><img src="https://img.shields.io/packagist/dt/hbenabdallah/phpgraph" alt="Téléchargements"></a>
<img src="https://img.shields.io/badge/php-%3E%3D8.2-777bb4" alt="PHP 8.2+">
<img src="https://img.shields.io/badge/php-%3E%3D8.5-777bb4" alt="PHP 8.5+">
<a href="https://github.com/hbenabdallah/phpgraph/blob/main/LICENSE"><img src="https://img.shields.io/badge/licence-MIT-blue" alt="Licence : MIT"></a>
<a href="https://mcpservers.org/servers/hbenabdallah/phpgraph"><img src="https://mcpservers.org/badge.svg" alt="Listed on mcpservers.org"></a>
</p>
Expand Down Expand Up @@ -62,7 +62,7 @@ $env:PHPGRAPH_VERSION = "dev-main"; irm https://raw.githubusercontent.com/hbenab

Le script télécharge le binaire, vérifie son SHA-256 et le place dans `~/.local/bin` (Windows : `%LOCALAPPDATA%\Programs\phpgraph`, ajouté au PATH) ; `PHPGRAPH_INSTALL_DIR` change le dossier. Le relancer met à jour. `dev-main` est reconstruit à chaque push sur `main` (la pré-version `edge`). Le binaire est un runtime PHP statique qui contient phpgraph, construit avec [static-php-cli](https://github.com/crazywhalecc/static-php-cli).

Avec PHP 8.2 ou plus, ou avec Docker :
Avec PHP 8.5 ou plus, ou avec Docker :

```bash
composer require --dev hbenabdallah/phpgraph # ou : composer global require hbenabdallah/phpgraph
Expand Down Expand Up @@ -135,7 +135,7 @@ phpgraph serve [chemin] # le serveur MCP, sur stdio
phpgraph mcp-config claude|codex|cursor|json [--docker image]
```

Options de `build` : `-e` pour exclure des chemins (répétable), `--no-vendor` pour ne pas lire les dépendances, `--no-cache` pour tout analyser à nouveau. `vendor`, `node_modules`, `var`, `.git` et les fichiers ignorés par les `.gitignore` du projet lui-même ne sont pas analysés ; un dépôt git au-dessus du projet n'applique jamais ses règles, si bien qu'un projet copié dans un dossier ignoré est quand même lu. Quand le dossier contient des fichiers PHP mais qu'ils sont tous exclus, `build` échoue en le disant, et chaque réponse MCP commence par cet avertissement au lieu de servir un graphe vide. La mémoire n'est pas limitée par défaut ; `PHPGRAPH_MEMORY_LIMIT=2G` fixe une limite. Avec PHP installé, opcache et son JIT accélèrent les builds d'environ 20 % : `php -d opcache.enable_cli=1 -d opcache.jit=tracing -d opcache.jit_buffer_size=128M vendor/bin/phpgraph build` (l'image Docker et les commandes affichées par `mcp-config` les utilisent déjà).
Options de `build` : `-e` pour exclure des chemins (répétable), `--no-vendor` pour ne pas lire les dépendances, `--no-cache` pour tout analyser à nouveau. `vendor`, `node_modules`, `var`, `.git` et les fichiers ignorés par les `.gitignore` du projet lui-même ne sont pas analysés ; un dépôt git au-dessus du projet n'applique jamais ses règles, si bien qu'un projet copié dans un dossier ignoré est quand même lu. Quand le dossier contient des fichiers PHP mais qu'ils sont tous exclus, `build` échoue en le disant, et chaque réponse MCP commence par cet avertissement au lieu de servir un graphe vide. La mémoire n'est pas limitée par défaut ; `PHPGRAPH_MEMORY_LIMIT=2G` fixe une limite. Les fichiers sont analysés par un processus par processeur, avec l'extension `pcntl` de PHP (dans les binaires et l'image Docker ; pas sous Windows, où ils sont analysés l'un après l'autre) : Sylius se construit en 10 s au lieu de 28 s sur un portable à 12 threads. `PHPGRAPH_WORKERS=4` fixe le nombre de processus, `PHPGRAPH_WORKERS=1` analyse dans un seul processus. Avec PHP installé, opcache et son JIT accélèrent les builds d'environ 20 % : `php -d opcache.enable_cli=1 -d opcache.jit=tracing -d opcache.jit_buffer_size=128M vendor/bin/phpgraph build` (l'image Docker et les commandes affichées par `mcp-config` les utilisent déjà).

## Ce que contient le graphe

Expand Down Expand Up @@ -332,7 +332,7 @@ Sylius (le commit du corpus), octobre 2026, sans LLM : phpgraph 1.0.2, [codebase

**Exécute-t-il mon code ?** Non. Il analyse les fichiers PHP et lit la configuration JSON, YAML et XML. Même `autoload_classmap.php` et les configurateurs de services PHP sont analysés, pas inclus.

**Quelles versions de PHP peut-il analyser ?** Tout ce que `nikic/php-parser` 5 sait lire : la syntaxe de PHP 7 et 8, et celle de PHP 4 et 5 retirée depuis (`$s{0}`, `=& new`, octaux comme `08`), pour un fichier que la grammaire la plus récente refuse. phpgraph lui-même demande PHP 8.2 ou plus.
**Quelles versions de PHP peut-il analyser ?** Tout ce que `nikic/php-parser` 5 sait lire : la syntaxe de PHP 7 et 8, et celle de PHP 4 et 5 retirée depuis (`$s{0}`, `=& new`, octaux comme `08`), pour un fichier que la grammaire la plus récente refuse. phpgraph lui-même demande PHP 8.5 ou plus.

**Avec quels agents fonctionne-t-il ?** Tout client MCP sur stdio : [Sherpa](https://github.com/hbenabdallah/sherpa), Claude Code, Codex, Cursor, Claude Desktop, et d'autres. `mcp-config` affiche la configuration des plus courants.

Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<a href="https://github.com/hbenabdallah/phpgraph/actions/workflows/ci.yml"><img src="https://github.com/hbenabdallah/phpgraph/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
<a href="https://packagist.org/packages/hbenabdallah/phpgraph"><img src="https://img.shields.io/packagist/v/hbenabdallah/phpgraph" alt="Packagist version"></a>
<a href="https://packagist.org/packages/hbenabdallah/phpgraph"><img src="https://img.shields.io/packagist/dt/hbenabdallah/phpgraph" alt="Downloads"></a>
<img src="https://img.shields.io/badge/php-%3E%3D8.2-777bb4" alt="PHP 8.2+">
<img src="https://img.shields.io/badge/php-%3E%3D8.5-777bb4" alt="PHP 8.5+">
<a href="https://github.com/hbenabdallah/phpgraph/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="License: MIT"></a>
<a href="https://mcpservers.org/servers/hbenabdallah/phpgraph"><img src="https://mcpservers.org/badge.svg" alt="Listed on mcpservers.org"></a>
</p>
Expand Down Expand Up @@ -62,7 +62,7 @@ $env:PHPGRAPH_VERSION = "dev-main"; irm https://raw.githubusercontent.com/hbenab

The script downloads the binary, checks its SHA-256 and puts it in `~/.local/bin` (Windows: `%LOCALAPPDATA%\Programs\phpgraph`, added to the PATH); `PHPGRAPH_INSTALL_DIR` changes the directory. Run it again to update. `dev-main` is rebuilt on every push to `main` (the `edge` pre-release). The binary is a static PHP runtime with phpgraph inside, built with [static-php-cli](https://github.com/crazywhalecc/static-php-cli).

With PHP 8.2+ installed, or with Docker:
With PHP 8.5+ installed, or with Docker:

```bash
composer require --dev hbenabdallah/phpgraph # or: composer global require hbenabdallah/phpgraph
Expand Down Expand Up @@ -135,7 +135,7 @@ phpgraph serve [path] # the MCP server, over stdio
phpgraph mcp-config claude|codex|cursor|json [--docker image]
```

`build` options: `-e` to exclude paths (repeatable), `--no-vendor` not to read dependencies, `--no-cache` to parse every file again. `vendor`, `node_modules`, `var`, `.git` and the files ignored by the project's own `.gitignore` files are skipped; a git repository above the project never applies its rules, so a project copied into an ignored directory is still read. When the directory holds PHP files but every one is excluded, `build` fails and says so, and every MCP answer starts with that warning instead of serving an empty graph. Memory is unlimited by default; `PHPGRAPH_MEMORY_LIMIT=2G` sets a limit. With PHP installed, opcache and its JIT make builds about 20% faster: `php -d opcache.enable_cli=1 -d opcache.jit=tracing -d opcache.jit_buffer_size=128M vendor/bin/phpgraph build` (the Docker image and the commands printed by `mcp-config` already use them).
`build` options: `-e` to exclude paths (repeatable), `--no-vendor` not to read dependencies, `--no-cache` to parse every file again. `vendor`, `node_modules`, `var`, `.git` and the files ignored by the project's own `.gitignore` files are skipped; a git repository above the project never applies its rules, so a project copied into an ignored directory is still read. When the directory holds PHP files but every one is excluded, `build` fails and says so, and every MCP answer starts with that warning instead of serving an empty graph. Memory is unlimited by default; `PHPGRAPH_MEMORY_LIMIT=2G` sets a limit. The files are parsed by one worker process per processor, with PHP's `pcntl` extension (in the binaries and the Docker image; not on Windows, where they are parsed one after the other): Sylius builds in 10 s instead of 28 s on a 12-thread laptop. `PHPGRAPH_WORKERS=4` sets the number of workers, `PHPGRAPH_WORKERS=1` parses in one process. With PHP installed, opcache and its JIT make builds about 20% faster: `php -d opcache.enable_cli=1 -d opcache.jit=tracing -d opcache.jit_buffer_size=128M vendor/bin/phpgraph build` (the Docker image and the commands printed by `mcp-config` already use them).

## What the graph contains

Expand Down Expand Up @@ -332,7 +332,7 @@ Sylius (the corpus commit), October 2026, without any LLM: phpgraph 1.0.2, [code

**Does it execute my code?** No. It parses PHP files and reads JSON, YAML and XML configuration. Even `autoload_classmap.php` and PHP service configurators are parsed, not included.

**Which PHP versions can it analyse?** Anything `nikic/php-parser` 5 parses: PHP 7 and 8 syntax, and the PHP 4 and 5 syntax removed since (`$s{0}`, `=& new`, octals like `08`), for a file the newest grammar rejects. phpgraph itself needs PHP 8.2 or newer.
**Which PHP versions can it analyse?** Anything `nikic/php-parser` 5 parses: PHP 7 and 8 syntax, and the PHP 4 and 5 syntax removed since (`$s{0}`, `=& new`, octals like `08`), for a file the newest grammar rejects. phpgraph itself needs PHP 8.5 or newer.

**Which agents does it work with?** Any MCP client over stdio: [Sherpa](https://github.com/hbenabdallah/sherpa), Claude Code, Codex, Cursor, Claude Desktop, and others. `mcp-config` prints the configuration for the common ones.

Expand Down
9 changes: 8 additions & 1 deletion bin/dev
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
#!/usr/bin/env sh
# Runs a command in a PHP container when PHP is not installed locally: bin/dev composer check
# The image is composer:2 with pcntl, which parses the files in worker processes (ParallelExtraction), built once;
# `docker rmi phpgraph-dev` makes the next run build it again from the latest composer:2.
# Host network: containers cannot reach a local DNS resolver such as systemd-resolved (127.0.0.53).
exec docker run --rm -i --network host -v "$(pwd)":/app -w /app -u "$(id -u):$(id -g)" -e COMPOSER_HOME=/tmp/composer composer:2 "$@"
IMAGE=phpgraph-dev
if ! docker image inspect "$IMAGE" >/dev/null 2>&1; then
printf 'FROM composer:2\nRUN apk add --no-cache --virtual .build $PHPIZE_DEPS && docker-php-ext-install pcntl && apk del .build\n' \
| docker build --network host -q -t "$IMAGE" - >&2 || exit 1
fi
exec docker run --rm -i --network host -v "$(pwd)":/app -w /app -u "$(id -u):$(id -g)" -e COMPOSER_HOME=/tmp/composer "$IMAGE" "$@"
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"source": "https://github.com/hbenabdallah/phpgraph"
},
"require": {
"php": ">=8.2",
"php": ">=8.5",
"nikic/php-parser": "^5.0",
"phpstan/phpdoc-parser": "^2.3",
"symfony/console": "^7.0",
Expand Down Expand Up @@ -74,7 +74,7 @@
},
"config": {
"platform": {
"php": "8.2.0"
"php": "8.5.0"
},
"sort-packages": true
}
Expand Down
Loading
Loading