Erste Schritte
Installation
Installiere Greph mit Composer:
composer require greph/greph
Dadurch werden die Bibliothek und vier ausführbare Dateien unter vendor/bin/ installiert:
greph: native Textsuche, AST-Suche und AST-Umschreibunggreph-index: aufgewärmter Textindex, AST-Faktenindex und Suche mit AST-Cacherg: Kompatibilitätswrapper im Stil von ripgrepsg: Kompatibilitätswrapper im Stil von ast-grep
Diese ausführbaren Dateien funktionieren ab Greph 0.2.3 im vendor/bin/ deines Projekts. Frühere Versionen fanden den Composer-Autoloader nur innerhalb eines Klons des Repositorys Greph. Verwende daher mindestens diese Version:
composer require greph/greph:^0.2.3
Voraussetzungen
- PHP 8.2+ für readonly-Klassen, Enums, First-Class-Callable-Syntax und Constructor Promotion
- ext-json für JSON-Ausgaben und Indexdaten auf der Festplatte
- ext-ctype für die Verarbeitung von Mustern und Optionen
- ext-tokenizer für den PHP-Parser und die AST-Vorfilter
- ext-zlib für den zwischengespeicherten AST-Speicher (
greph-index ast-cache) - nikic/php-parser (wird automatisch als Composer-Abhängigkeit installiert)
ext-json, ext-ctype und ext-tokenizer sind in fast jedem PHP-Build aktiviert. composer.json deklariert derzeit nur ext-json (#5), daher gibt Composer keine Warnung aus, wenn eine der anderen Erweiterungen fehlt.
Optional:
- ext-pcntl für parallele Scans. Greph wechselt bei fehlender Erweiterung problemlos zur Ausführung in einem einzelnen Prozess.
- Externe
rg-,grep- undsg-Binärdateien für Benchmark-Vergleiche. Zur Laufzeit werden sie nie benötigt.
Suchen, Umschreiben und Indexieren rufen proc_open() oder shell_exec() nie auf; nur parallele Scans starten Unterprozesse und fallen ohne pcntl_fork() auf einen einzelnen Prozess zurück. Unter Hosts mit eingeschränkten Prozessen erfährst du mehr zu Hosts, die proc_open(), shell_exec() oder pcntl_fork() deaktivieren.
Deine erste Textsuche
Der Standardmodus von Greph ist eine grep-kompatible Textsuche:
vendor/bin/greph -F "function" src
Die Ausgabe verwendet das kanonische file:line:content-Format, das grep, ripgrep und die meisten Editor-Integrationen erwarten.
src/Greph.php:41: public static function walk(string|array $paths, ?WalkOptions $options = null): FileList
src/Greph.php:50: public static function searchText(string $pattern, string|array $paths, ?TextSearchOptions $options = null): array
src/Greph.php:81: public static function buildTextIndex(
Füge -i für die Suche ohne Beachtung der Groß- und Kleinschreibung hinzu, -w für ganze Wörter, -c für Trefferzahlen, -l nur für Dateipfade, -C 2 für zwei Kontextzeilen und vieles mehr. Die vollständige Liste findest du in der Referenz zu CLI.
Deine erste AST-Suche
Übergib -p und ein Muster im Format PHP, um zur strukturellen Suche zu wechseln:
vendor/bin/greph -p 'new $CLASS()' src
$CLASS ist eine Metavariable, die jeden Klassennamen erfasst. Das Muster new $CLASS() findet jeden new-Ausdruck ohne Argumente, unabhängig von Klasse, Formatierung oder Kommentaren. Mit new $CLASS($$$ARGS) findest du Aufrufe mit beliebigen Argumenten.
Jeder AST-Treffer wird mit Datei, Startzeile und passendem Code ausgegeben:
src/Greph.php:43:new FileWalker()
src/Greph.php:52:new TextSearchOptions()
src/Greph.php:54:new TextSearcher()
Weitere nützliche Muster:
# Any method call with any arguments
vendor/bin/greph -p '$obj->$method($$$ARGS)' src
# Any function declaration with a void return type
vendor/bin/greph -p 'function $name($$$PARAMS): void {}' src
# Old-style array calls
vendor/bin/greph -p 'array($$$ITEMS)' src
Die vollständige Mustersyntax findest du unter Modi / AST-Suche.
Dein erstes Rewrite
Füge -r hinzu, um die AST-Suche in ein Rewrite umzuwandeln:
# Preview only
vendor/bin/greph -p 'array($$$ITEMS)' -r '[$$$ITEMS]' --dry-run src
# Apply
vendor/bin/greph -p 'array($$$ITEMS)' -r '[$$$ITEMS]' src
# Confirm each file before writing
vendor/bin/greph -p 'array($$$ITEMS)' -r '[$$$ITEMS]' --interactive src
Bei Rewrites bleibt die Formatierung außerhalb des Treffers erhalten: Nur der passende Knoten wird ersetzt, Leerzeichen, Einrückungen und Kommentare im Umfeld bleiben unverändert. Der Knoten selbst wird anhand der Vorlage neu ausgegeben, wodurch seine Formatierung vereinheitlicht werden kann. Ein Kommentar innerhalb des Knotens kann dabei verloren gehen. Details findest du unter Modi / Rewrite.
PHP API
Die statische Fassade Greph\Greph bietet dieselben Operationen wie die CLI:
use Greph\Greph;
use Greph\Ast\AstSearchOptions;
use Greph\Text\TextSearchOptions;
$results = Greph::searchText(
'function',
'src',
new TextSearchOptions(fixedString: true, caseInsensitive: true),
);
foreach ($results as $file) {
foreach ($file->matches as $match) {
echo "{$file->file}:{$match->line}:{$match->content}\n";
}
}
$matches = Greph::searchAst(
'new $CLASS()',
'src',
new AstSearchOptions(),
);
foreach ($matches as $match) {
echo "{$match->file}:{$match->startLine}:{$match->code}\n";
}
Den vollständigen Funktionsumfang findest du unter API.
Indexierte Suche
Bei wiederholten Aufgaben profitierst du von aufgewärmten Indizes. Erstelle den Index einmal und führe dann beliebig viele Abfragen aus:
# Text index
vendor/bin/greph-index build .
vendor/bin/greph-index search -F "function" .
# AST fact index
vendor/bin/greph-index ast-index build .
vendor/bin/greph-index ast-index search 'new $CLASS()' src
# Cached parsed-tree index
vendor/bin/greph-index ast-cache build .
vendor/bin/greph-index ast-cache search 'array($$$ITEMS)' src
Standardmäßig liegen die Indizes im Projektstammverzeichnis unter .greph-index, .greph-ast-index und .greph-ast-cache.
Wähle für Bäume, die sich häufig ändern, ein Lebenszyklusprofil, anstatt alle aufgewärmten Indizes gleich zu behandeln:
vendor/bin/greph-index build . --lifecycle static
vendor/bin/greph-index build . \
--lifecycle opportunistic-refresh \
--auto-refresh-max-files 32 \
--auto-refresh-max-bytes 1048576
vendor/bin/greph-index stats . --dry-refresh
Das übliche Vorgehen:
- eine stabile Ausgangsbasis als
staticbehalten - häufig geänderte Overlays als
opportunistic-refreshbehalten - veraltetes Verhalten mit
stats --dry-refreshprüfen
Suche mit mehreren aufgewärmten Indizes
Du kannst mehrere aufgewärmte Indizes mit einem einzigen Befehl durchsuchen:
vendor/bin/greph-index search -F "apply_filters" . \
--index-dir wordpress/.greph-index \
--index-dir wp-content/plugins/my-plugin/.greph-index \
--show-index-origin
vendor/bin/greph-index ast-index search 'new $CLASS()' . \
--index-dir wordpress/.greph-ast-index \
--index-dir wp-content/plugins/my-plugin/.greph-ast-index \
--show-index-origin
Benannte Indexgruppen
Wenn du das regelmäßig tust, speichere das Layout in .greph-index-set.json und nutze die Unterbefehle für Gruppen, statt die Flags jedes Mal neu anzugeben:
vendor/bin/greph-index set build
vendor/bin/greph-index set stats --dry-refresh
vendor/bin/greph-index set search --show-index-origin -F "apply_filters" .
vendor/bin/greph-index set search --mode ast-index 'new $CLASS()' .
vendor/bin/greph-index set search --mode ast-cache 'array($$$ITEMS)' .
Planner-Trace
Um zu sehen, wie die aufgewärmte Suche die Kandidaten eingrenzt, füge --trace-plan hinzu:
vendor/bin/greph-index search --trace-plan -F "function" .
vendor/bin/greph-index ast-index search --trace-plan 'new $CLASS()' .
Den vollständigen Ablauf der aufgewärmten Suche findest du unter Indexiert / Text und Indexiert / AST.
Kompatibilitäts-Wrapper
Wenn deine Tools oder Agents bereits ripgrep oder ast-grep verwenden, kannst du einfach die Wrapper einsetzen:
vendor/bin/rg --json -F "function" src
vendor/bin/sg --pattern 'new $CLASS()' src --lang php
Beide Wrapper verwenden dieselbe Engine und wurden durch Tests mit den vorgelagerten Binärdateien geprüft. Die verifizierten Funktionen sind unter Kompatibilität / rg und Kompatibilität / sg dokumentiert und in der generierten Funktionsmatrix aufgeführt.
Konfiguration
Greph berücksichtigt zwei Konventionen für Dateien auf der Festplatte:
.gitignore: wird standardmäßig berücksichtigt. Mit--no-ignorekannst du das deaktivieren..grephignore: gleiche Syntax wie.gitignore, wird zusätzlich angewendet. Damit kannst du werkzeugspezifische Ausschlüsse festlegen, die du nicht in der Versionsverwaltung speichern möchtest.
Die Standardverzeichnisse der Indizes sind am gewählten Stammverzeichnis .greph-index, .greph-ast-index und .greph-ast-cache. Du kannst sie mit --index-dir bei jedem greph-index-Unterbefehl überschreiben oder mit .greph-index-set.json wiederverwendbare Layouts für mehrere Indizes nutzen.