はじめに
Grephは、ソースツリー向けの純粋なPHP検索・リファクタリングエンジンです。次の3つの関連モードを備えています:
- テキスト検索: grep互換の出力とripgrep風の使いやすさ
- AST検索: PHPの構造パターンとメタ変数に対応
- AST書き換え: 書式を保った構造リファクタリング
テキストとASTの両方で、事前作成済みインデックスを使ったモード、ライフサイクルに応じた更新ポリシー、マニフェストを使ったインデックスセット、同じエンジンを利用するrg / sg互換ラッパーも提供します。
Grephが作られた理由
高速なコード検索が必要なPHPアプリやエージェントは、通常ネイティブツール(grep、ripgrep、ast-grep)を外部から実行するため、移植性が損なわれ、デプロイの負担も増えます。構造検索や書き換えでは、さらに問題が大きく、通常はPHPのプロセスを完全に離れる必要があります。
Grephはこの隔たりを解消します。PHPコードから、標準ライブラリとnikic/php-parserだけを使って、テキスト検索、構造マッチング、リファクタリングの書き換えを実行できます。出力と終了コードは標準ツールと互換性があるため、既存のスクリプトやエージェントを変更する必要はありません。
機能
- 固定文字列と正規表現によるテキスト検索。単語全体、大文字と小文字の区別、前後行、件数、ファイルのみの各モードに対応
- PHPの構造AST検索。
$VAR、$$$VARIADIC、繰り返し使うメタ変数に対応 - 書式を保ったAST書き換え。ドライラン、対話型、書き込みの各モードに対応
- 繰り返し処理向けの事前作成済みテキストインデックス(トライグラム + 識別子の投稿リスト)
- 繰り返し行う構造クエリ向けの事前作成済みASTファクトインデックスとキャッシュ済みAST検索
- ライフサイクルに応じた事前作成済みインデックス:
static、manual-refresh、opportunistic-refresh、strict-stale-check - テキスト、ASTファクト、ASTキャッシュのストアを横断する複数インデックス検索と名前付きセット検索
--trace-planによるプランナー診断と、事前作成済み検索でのインデックス元のラベル表示- 同じエンジンを使用するripgrepとast-grepのCLI互換ラッパー
- 単一プロセスへのフォールバックに対応した、pcntlベースの並列ワーカープール
- バイナリ検出に対応した、gitignoreおよび
.grephignore準拠のファイルウォーカー
必要な環境
- PHP 8.2以降
- ほぼすべてのPHPビルドで有効な
ext-json、ext-ctype、ext-tokenizer - キャッシュ済みASTストア(
greph-index ast-cache)用のext-zlib nikic/php-parser(Composerの依存関係はこれのみ)
テキストとASTの主要機能は純粋なPHPで動作します。ベンチマークの比較には、rg、grep、sgなどの外部ツールが必要ですが、Grephの動作には不要です。並列スキャンではext-pcntlが利用可能なら使用し、利用できない場合は単一プロセスに切り替わります。proc_open()とshell_exec()を禁止しているホストについては、プロセスが制限されたホストを参照してください。
使用例
vendor/bin実行ファイルは、プロジェクトの依存関係としてGrephをインストールする場合、Greph 0.2.3以降を必要とします。
# Text search
vendor/bin/greph -F "function" src
# Structural search
vendor/bin/greph -p 'new $CLASS()' src
# Structural rewrite preview
vendor/bin/greph -p 'array($$$ITEMS)' -r '[$$$ITEMS]' --dry-run src
use Greph\Greph;
use Greph\Ast\AstSearchOptions;
use Greph\Text\TextSearchOptions;
$matches = Greph::searchText(
'function',
'src',
new TextSearchOptions(fixedString: true),
);
$asts = Greph::searchAst(
'new $CLASS()',
'src',
new AstSearchOptions(),
);
$rewrites = Greph::rewriteAst(
'array($$$ITEMS)',
'[$$$ITEMS]',
'src',
);
まずははじめにを確認し、続いてCLIとAPIで機能全体を確認してください。モード、インデックス、互換性の各セクションでは、具体的な使い方を詳しく説明しています。