Greph
Pesquisa de código PHP pura, pesquisa estrutural e mecanismo de reescrita. Fluxos de trabalho com grep, ripgrep e ast-grep em um único pacote Composer.
composer require greph/grephVersão mais recente 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)' srcNa prática
Instale o pacote com Composer e, em seguida, pesquise e reescreva pela linha de comando ou em PHP.
Pesquise, encontre correspondências e visualize uma reescrita
-F executa uma pesquisa de texto por string literal; -p recebe um padrão no formato PHP, com met variáveis como $CLASS; e -r adiciona um modelo de substituição. --dry-run exibe os arquivos reescritos sem gravá-los.
A fachada estática Greph expõe as mesmas operações a código PHP. Quando instalados como dependência, os comandos vendor/bin exigem a versão 0.2.3 ou posterior.
# 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 puro
A pesquisa e a reescrita são executadas em PHP 8.2+, sem binários de grep, ripgrep ou ast-grep. Usa as extensões json, ctype e tokenizer, além de zlib para o armazenamento em cache da AST.
Pesquisa de texto
Pesquisa por string literal e regex com modos de palavra inteira, sem distinção entre maiúsculas e minúsculas, contexto, contagem e somente arquivos. Saída compatível com grep.
Pesquisa AST
Pesquisa estrutural de código PHP com metavariáveis $VAR e $$$VARIADIC, capturas repetidas e saída JSON. PHP é a única linguagem compatível.
Reescrita AST
Reescritas estruturais com modos de simulação, interativo e gravação. Só o código correspondente é alterado; comentários e formatação fora da correspondência permanecem como estavam.
Modos indexados
Crie uma vez um índice de texto por trigramas, um índice de fatos da AST ou um armazenamento em cache da AST e reutilize-o. No benchmark do projeto, o índice de fatos da AST levou 1.4 s para ser criado e reduziu new $CLASS() de 2.9 s para 11 ms; o índice de trigramas levou 12.3 s.
Wrappers rg e sg
vendor/bin/rg e vendor/bin/sg aceitam os sinalizadores de pesquisa comuns de ripgrep e ast-grep no mesmo mecanismo. Não são compatíveis: pesquisa em várias linhas, --replace, --type-add e --sort no rg; regras YAML e linguagens não PHP no sg.
PHP API
Greph::searchText(), searchAst() e rewriteAst() retornam objetos de resultado tipados, para que código PHP e agentes chamem o mecanismo sem um subprocesso.
Corpus de referência
39 cenários comparam por diff a saída de texto, AST e reescrita do greph com grep, ripgrep e ast-grep. Execute-os com composer test:oracle em um clone do repositório; a CI executa as suítes de unidade e integração.
Por que Greph
Sem binários nativos
A pesquisa e a reescrita são executadas dentro do processo PHP. Os binários rg, grep e sg são usados apenas nas comparações opcionais de benchmark.
Um mecanismo para todos os modos
A pesquisa de texto, a pesquisa estrutural PHP e a reescrita fazem parte de um único pacote Composer. Os wrappers rg e sg chamam o mesmo mecanismo que vendor/bin/greph.
As reescritas alteram apenas as correspondências
O reescritor insere o modelo renderizado nos intervalos de bytes correspondentes. O código fora das correspondências mantém o recuo, os comentários e as linhas em branco.
Índices aquecidos sem um daemon
Os índices ficam no disco e são reutilizados entre execuções. Um perfil de ciclo de vida decide se um índice desatualizado é mantido, atualizado durante a pesquisa ou recusado.
Comparação com
Greph mantém a pesquisa e a reescrita em PHP. Essas ferramentas resolvem problemas relacionados e fazem algumas coisas que Greph não faz.
| Ferramenta | Ideal para | Diferenças em relação a Greph |
|---|---|---|
| ripgrep | Ideal paraUma ferramenta de pesquisa recursiva com regex e suporte de primeira classe a Windows, macOS e Linux, além de downloads de binários em cada versão. Respeita as regras do gitignore e, por padrão, ignora arquivos ocultos e binários. | Diferenças em relação a GrephGreph é instalado com Composer e executado em PHP. No benchmark de CI do corpus WordPress, o rg foi mais rápido em todas as consultas de texto sem índice aquecido, por exemplo, 81.62 ms contra 458.82 ms em uma pesquisa literal. Um índice Greph aquecido respondeu a uma consulta de contagem em 10.90 ms, contra 49.61 ms do rg. |
| ast-grep | Ideal paraUm CLI compilado para pesquisa estrutural, lint e reescrita, desenvolvido com tree-sitter. Tem suporte integrado a muitas linguagens, entre elas PHP, e arquivos de regras YAML para lint e alterações de código. | Diferenças em relação a GrephGreph lida apenas com PHP e não lê regras YAML. Em uma varredura sem índice aquecido, o sg foi mais rápido em array($$$ITEMS) no benchmark de CI de Greph. O índice AST aquecido de Greph respondeu a new $CLASS() em 10.89 ms, contra 4093.61 ms do sg. |
| Rector | Ideal paraAtualiza e refatora código PHP com regras e conjuntos de regras, abrangendo as versões PHP de 5.3 a 8.5 e projetos como Symfony, PHPUnit e Doctrine. | Diferenças em relação a GrephGreph reescreve código com base em um padrão e um modelo que você cria. A documentação desaconselha seu uso quando uma alteração depende de informações de tipos que PHP-Parser não consegue resolver a partir de um único arquivo ou exige adicionar ou remover imports entre arquivos. |
| PHP CS Fixer | Ideal paraCorrige o código para seguir os padrões de codificação, com conjuntos de regras integrados, como o estilo de código PER do PHP-FIG. | Diferenças em relação a GrephGreph não reformata arquivos. Altera apenas o código correspondente ao padrão, e a documentação indica PHP CS Fixer quando você precisa de um formatador. |
Perguntas e respostas
Respostas curtas da documentação do Greph.
Não. Greph executa a pesquisa e a reescrita em PHP. Os binários externos rg, grep e sg são usados apenas nas comparações opcionais de benchmark.
Somente PHP. Os padrões e arquivos de código-fonte são analisados com nikic/php-parser, e qualquer outro valor de --lang é rejeitado como incompatível.
Não em varreduras sem índice aquecido. No benchmark de CI do projeto, executado no corpus WordPress, rg e grep foram mais rápidos em todas as consultas de texto sem índice aquecido. Índices aquecidos ajudam em consultas repetidas; por exemplo, uma consulta de contagem indexada levou 10.90 ms contra 49.61 ms do rg.
Greph é executado em processo único. Sem pcntl_fork, o pool de workers processa cada bloco no mesmo processo, com o mesmo resultado de -j 1, sem gerar erros.
Fora das correspondências, não. O código fora dos intervalos de bytes correspondentes mantém os espaços em branco, os comentários e a formatação. O código correspondente é impresso novamente a partir do modelo, então suas quebras de linha são normalizadas e um comentário dentro dele pode se perder. Execute primeiro com --dry-run para exibir os arquivos reescritos sem gravá-los.
Por padrão, em .greph-index, .greph-ast-index e .greph-ast-cache, na raiz indexada. Passe --index-dir a qualquer subcomando greph-index para usar outro local.
Leia a documentação de Greph para consultar a referência de CLI, a PHP API, os modos indexados e os wrappers rg e sg.