Greph
纯 PHP 代码搜索、结构化搜索和重写引擎。在单个 Composer 包中提供 grep、ripgrep 和 ast-grep 工作流。
composer require greph/greph最新版本 v0.2.3 MIT PHP 8.2+
# 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实践应用
使用 Composer 安装此包,然后从命令行或 PHP 中搜索和重写。
搜索、匹配并预览重写结果
-F 执行固定字符串文本搜索,-p 接受带有元变量的 PHP 风格模式,例如 $CLASS,而 -r 会添加替换模板。--dry-run 会打印重写后的文件,但不会写入文件。
静态 Greph 门面向 PHP 代码提供相同操作。作为依赖安装时,vendor/bin 命令要求版本不低于 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 srcuse 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(),
);纯 PHP
搜索和重写在 PHP 8.2+ 中运行,无需 grep、ripgrep 或 ast-grep 二进制文件。使用 json、ctype 和 tokenizer 扩展,以及用于缓存 AST 存储的 zlib。
文本搜索
支持固定字符串和正则表达式搜索,并提供整词、忽略大小写、上下文、计数和仅文件模式。输出与 grep 兼容。
AST 搜索
对 PHP 源代码进行结构化搜索,支持 $VAR 和 $$$VARIADIC 元变量、重复捕获以及 JSON 输出。PHP 是唯一受支持的语言。
AST 重写
支持试运行、交互式和写入模式的结构化重写。只更改匹配到的代码;匹配范围之外的注释和布局保持原样。
索引模式
构建一次三元组文本索引、AST 事实索引或缓存 AST 存储,然后重复使用。在项目基准测试中,构建 AST 事实索引用时 1.4 s,将 new $CLASS() 从 2.9 s 缩短至 11 ms;三元组索引用时 12.3 s。
rg 和 sg 封装器
vendor/bin/rg 和 vendor/bin/sg 在同一引擎上接受常用的 ripgrep 和 ast-grep 搜索标志。未涵盖:rg 中的多行、--replace、--type-add 和 --sort;sg 中的 YAML 规则和非 PHP 语言。
PHP API
Greph::searchText()、searchAst() 和 rewriteAst() 会返回类型化结果对象,因此 PHP 代码和智能体无需启动子进程即可调用该引擎。
Oracle 测试语料库
39 个场景会将 greph 的文本、AST 和重写输出与 grep、ripgrep 和 ast-grep 进行差异比较。在仓库克隆中运行 composer test:oracle;CI 会运行单元测试和集成测试套件。
为什么选择 Greph
无需原生二进制文件
搜索和重写在 PHP 进程内运行。rg、grep 和 sg 二进制文件仅用于可选的基准测试比较。
所有模式共用一个引擎
文本搜索、PHP 结构化搜索和重写都集成在一个 Composer 包中。rg 和 sg 封装器调用的引擎与 vendor/bin/greph 相同。
重写只修改匹配项
重写器会将渲染后的模板拼接到匹配的字节范围内。匹配范围之外的代码会保留原有的缩进、注释和空行。
索引预热后可用,无需守护进程
索引保存在磁盘上,并在多次运行间重复使用。生命周期配置文件决定过期索引是保持不变、在搜索期间刷新,还是被拒绝使用。
对比
Greph 将搜索和重写集成在 PHP 中。这些工具解决的问题彼此相关,而 Greph 有些功能不具备。
| 工具 | 擅长领域 | 与 Greph 的区别 |
|---|---|---|
| ripgrep | 擅长领域一款递归正则表达式搜索工具,在 Windows、macOS 和 Linux 上提供一流支持,并为每个版本提供二进制下载。它遵循 gitignore 规则,默认跳过隐藏文件和二进制文件。 | 与 Greph 的区别Greph 使用 Composer 安装,并在 PHP 中运行。在其 CI 基准测试中,针对 WordPress 语料库,rg 在每次冷文本查询中都更快,例如字面量搜索耗时 81.62 ms,而 458.82 ms。预热的 Greph 索引在 10.90 ms 内完成计数查询,而 rg 耗时 49.61 ms。 |
| ast-grep | 擅长领域一个编译后的 CLI,基于 tree-sitter 构建,用于结构化搜索、代码检查和重写。它内置了对多种语言的支持,其中包括 PHP,并提供 YAML 规则文件来定义代码检查规则和代码更改。 | 与 Greph 的区别Greph 仅处理 PHP,且不读取 YAML 规则。在 Greph 的 CI 基准测试中,冷扫描时 sg 对 array($$$ITEMS) 的处理速度更快。Greph 的预热 AST 索引在 10.89 ms 内完成 new $CLASS(),而 sg 耗时 4093.61 ms。 |
| Rector | 擅长领域通过规则和规则集升级并重构 PHP 代码,涵盖从 5.3 到 8.5 的 PHP 版本,以及 Symfony、PHPUnit 和 Doctrine 等项目。 | 与 Greph 的区别Greph 根据你编写的模式和模板进行重写。其文档指出,如果更改依赖于 PHP-Parser 无法从单个文件解析的类型信息,或者需要跨文件添加或删除导入,则不适合使用该工具。 |
| PHP CS Fixer | 擅长领域修复代码以符合编码标准,内置规则集包括 PHP-FIG 的 PER 编码风格。 | 与 Greph 的区别Greph 不会重新格式化文件。它只更改模式匹配到的代码;如果需要格式化工具,其文档会指向 PHP CS Fixer。 |
问答
来自 Greph 文档的简明解答。
不需要。Greph 在 PHP 中运行搜索和重写。外部 rg、grep 和 sg 二进制文件仅用于可选的基准测试比较。
仅支持 PHP。模式和源文件使用 nikic/php-parser 进行解析,任何其他 --lang 值都会因不受支持而被拒绝。
冷扫描时并不快。在该项目针对 WordPress 语料库的 CI 基准测试中,rg 和 grep 在每次冷文本查询中都更快。预热索引有助于重复查询,例如索引计数查询耗时 10.90 ms,而 rg 耗时 49.61 ms。
Greph 会以单进程方式运行。没有 pcntl_fork 时,工作进程池会在进程内运行每个数据块,结果与 -j 1 相同,且不会报错。
匹配范围之外不会。匹配字节范围之外的代码会保留原有空白、注释和布局。匹配到的代码会根据模板重新打印,因此其中的换行会被规范化,内部注释也可能丢失。请先使用 --dry-run 运行,以打印重写后的文件而不写入文件。
默认存储在索引根目录下的 .greph-index、.greph-ast-index 和 .greph-ast-cache 中。向任意 greph-index 子命令传入 --index-dir 可指定其他位置。
阅读 Greph 文档,了解 CLI 参考、PHP API、索引模式以及 rg 和 sg 封装器。